Exception caught by widgets library - Bad state - flutter

import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class ChatScreen extends StatefulWidget {
static const String screenRoute = 'chat_screen';
const ChatScreen({Key? key}) : super(key: key);
#override
State<ChatScreen> createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> {
final _firestore = FirebaseFirestore.instance;
final _auth = FirebaseAuth.instance;
late User signedInUser;
String? messageText;
#override
void initState() {
super.initState();
getCurrentUser();
}
void getCurrentUser() {
try {
final user = _auth.currentUser;
if (user != null) {
signedInUser = user;
print(signedInUser.email);
}
} catch (e) {
print(e);
}
}
//void getMessages() async {
// final messages = await _firestore.collection('messages').get();
//for (var message in messages.docs) {
// print(message.data());
// }
//}
void messagesStream() async {
await for (var snapshot in _firestore.collection('messages').snapshots()) {
for (var message in snapshot.docs) {
print(message.data());
}
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.yellow[900],
title: Row(
children: [
Image.asset('assets/images/logo.png', height: 25),
const SizedBox(width: 10),
const Text('ChatMe'),
],
),
actions: [
IconButton(
onPressed: () {
messagesStream();
//_auth.signOut();
//Navigator.pop(context);
},
icon: const Icon(Icons.download),
),
],
),
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
StreamBuilder<QuerySnapshot>(
stream: _firestore.collection('messages').snapshots(),
builder: (context, snapshot) {
List<Text> messageWidgets = [];
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(
backgroundColor: Colors.blue,
),
);
}
final messages = snapshot.data!.docs;
for (var message in messages) {
final messageText = message.get('text');
final messageSender = message.get('sender');
final messageWidget = Text('$messageText - $messageSender');
messageWidgets.add(messageWidget);
}
return ListView(
children: messageWidgets,
);
},
),
Container(
decoration: const BoxDecoration(
border: Border(
top: BorderSide(
color: Colors.orange,
width: 2,
),
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: TextField(
onChanged: (value) {
messageText = value;
},
decoration: const InputDecoration(
contentPadding: EdgeInsets.symmetric(
vertical: 10,
horizontal: 20,
),
hintText: 'Write Your Message Here..',
border: InputBorder.none,
),
),
),
TextButton(
onPressed: () {
_firestore.collection('messages').add({
'text': messageText,
'sender': signedInUser.email,
});
},
child: Text(
'send',
style: TextStyle(
color: Colors.blue[800],
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
),
],
),
),
],
),
),
);
}
}
════════ Exception caught by widgets library ═══════════════════════════════════
Bad state: field does not exist within the DocumentSnapshotPlatform
The relevant error-causing widget was
StreamBuilder<QuerySnapshot<Object?>>
lib\…\screens\chat_screen.dart:82
════════════════════════════════════════════════════════════════════════════════

Related

Search from a list of Firebase Users with TextField and StreamProvider in Flutter

I'm building a chat app with Firebase in flutter and I want to be able to search from a list of users,. I also want that when no text is typed, no user should be shown
I tried a lot of things but I never got it right. This is what I did :
search_page.dart:
class SearchPage extends StatefulWidget {
const SearchPage({Key? key}) : super(key: key);
#override
State<SearchPage> createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
TextEditingController searchController = TextEditingController();
#override
void initState() {
super.initState();
searchController.addListener(_onSearchChanged);
}
_onSearchChanged() {
print(searchController.text);
}
#override
void dispose() {
searchController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return StreamProvider<List<AppUserData>>.value(
initialData: [],
value: DatabaseService().users,
child: Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: dDarkGrey,
body:
Column(crossAxisAlignment: CrossAxisAlignment.center, children: [
const SizedBox(
height: 3,
),
Stack(
alignment: Alignment.center,
children: [
Container(
height: 90,
decoration: BoxDecoration(color: dDarkGrey, boxShadow: [
BoxShadow(
color: dBlack.withOpacity(0.16),
spreadRadius: 3,
blurRadius: 3,
offset: const Offset(0, 4))
]),
),
Column(
children: [
const SizedBox(
height: 20,
),
Row(
children: [
IconButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const HomePage()));
},
icon: const Icon(SocketIconv2.ic_back),
color: dLightGrey,
),
SizedBox(
width: MediaQuery.of(context).size.width - 60,
child: TextField(
enabled: true,
controller: searchController,
style: const TextStyle(color: dLightGrey),
decoration: const InputDecoration(
contentPadding:
EdgeInsets.fromLTRB(0, 0, 0, 0),
filled: true,
fillColor: dDarkGrey,
prefixIcon: Icon(
SocketIconv2.ic_search,
color: dLightGrey,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(15))),
hintStyle: TextStyle(
color: dLightGrey,
fontFamily: 'SegoeUI',
fontSize: 18,
fontWeight: FontWeight.w300),
hintText: 'Search',
))),
],
),
],
),
],
),
// search bar
SizedBox(
height: MediaQuery.of(context).size.height - 95,
width: MediaQuery.of(context).size.width,
child: SearchList(
controller: searchController,
),
)
])),
);
}
}
search_list.dart:
class SearchList extends StatelessWidget {
SearchList({Key? key, required this.controller}) : super(key: key);
final TextEditingController controller;
#override
Widget build(BuildContext context) {
final users = Provider.of<List<AppUserData>>(context);
return Scaffold(
backgroundColor: Colors.transparent,
body: ListView.separated(
itemBuilder: (context, index) {
if (controller.text.isEmpty) {
return Container();
}
if (controller.text.isNotEmpty) {
return searchAccount(context, name, username, users[index]);
}
if (users[index].name.startsWith(controller.text.toLowerCase())) {
return searchAccount(context, name, username, users[index]);
} else {
return Container();
}
},
itemCount: users.length,
separatorBuilder: (context, index) => const SizedBox(height: 20),
));
}
}
search_account.dart:
Widget searchAccount(
BuildContext context, String name, String username, AppUserData users) {
return Row(
children: [
const SizedBox(
width: 20,
),
Row(
children: [
ClipOval(
child: Image.asset(
imagePp,
scale: 9,
),
),
const SizedBox(
width: 30,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(users.name,
style: SegoeUiPreset(dLightGrey).customTileName()),
Text(users.username,
style: SegoeUiPreset(dLightGrey).customTileSubtitle())
],
)
],
),
],
);
}
user.dart:
class AppUser {
final String? uid;
AppUser({this.uid});
}
class AppUserData {
final String? uid;
final String name;
final String username;
AppUserData({this.uid, required this.name, required this.username});
}
database.dart:
class DatabaseService {
final String? uid;
DatabaseService({this.uid});
final CollectionReference chatRoomCollection =
FirebaseFirestore.instance.collection("chatrooms");
final CollectionReference userCollection =
FirebaseFirestore.instance.collection("users");
Future<void> saveUser(String name, String username) async {
return await userCollection
.doc(uid)
.set({'name': name, 'username': username});
}
AppUserData _userFromSnapshot(DocumentSnapshot snapshot) {
return AppUserData(
name: snapshot['name'],
uid: snapshot.id,
username: snapshot['username']);
}
Stream<AppUserData> get user {
return userCollection.doc(uid).snapshots().map(_userFromSnapshot);
}
List<AppUserData> _userListFromSnapshot(QuerySnapshot snapshot) {
return snapshot.docs.map((doc) {
return _userFromSnapshot(doc);
}).toList();
}
Stream<List<AppUserData>> get users {
return userCollection.snapshots().map(_userListFromSnapshot);
}
}
Got any hints ? I'm a begginner :/
Thank you in advance :)

How to properly record local storage(sharedpreferences) for a list(todolist)

I am new to flutter. I have a task to create a local repository for a task list. I tried many options to write the code but none of them worked. I read and watched a lot of videos and articles. Please write your options how I can record it
Here is my code:
import 'dart:convert';
import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Home extends StatefulWidget {
const Home ({key}): super(key: key);
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
final myController = TextEditingController();
bool submit = false;
Color mainColor = Color(0xFFEEEFF5);
Color secColor = Color(0xFF3A3A3A);
Color tdBlue = Color(0xFF5F52EE);
String temp = "";
List todoList = [];
#override
void initState() {
super.initState();
myController.addListener(() {
setState(() {
submit = myController.text.isNotEmpty;
});
});
todoList.addAll(['Biy milk','Dishhh Wash','Придбати картоплю', 'Buy cucumbers', 'Kylunuch'],);
}
#override
void dispose() {
// Clean up the controller when the widget is disposed.
myController.dispose();
super.dispose();
}
void clearText() {
myController.clear();
}
#override
Widget build(BuildContext context){
return Scaffold(
backgroundColor: mainColor,
appBar: AppBar(
elevation: 0.0,
backgroundColor: secColor,
title: Text ('ToDo - List', style: TextStyle(fontSize: 26.5, fontWeight: FontWeight.bold, fontStyle: FontStyle.italic),),
),
body: Column(
children: [
Container(
margin: EdgeInsets.only(
top: 15.0,
left: 13.0,
right: 8.0,
),
child: Row(
children: [
Expanded(
child: TextField(
onChanged: (String value) {
temp = value;
},
controller: myController,
decoration:
InputDecoration(
prefixIcon: Icon(Icons.notes, color: Colors.orangeAccent,),
labelText: 'Замітка',
hintText: 'Введіть замітку',
filled: true,
fillColor: Colors.white,
border: OutlineInputBorder(),
contentPadding: EdgeInsets.all(10.0),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(30.0),),
),
),
),
),
SizedBox(
width: 10.0,
),
ElevatedButton(
style: ElevatedButton.styleFrom(backgroundColor: tdBlue),
onPressed:
submit ? () => submitData() : null,
child:
Text('+', style: TextStyle(fontSize: 35),),
),
], // Закривається 2-ий чілдрен
), //Row 1-ий
),
Expanded(
child: Padding(
padding: EdgeInsets.only(
top: 15.0,
),
child: ListView.builder(
itemCount: todoList.length,
itemBuilder: (BuildContext context, int index){
return Dismissible(
key: Key(todoList[index]),
child: Card(
margin: EdgeInsets.only(
top: 16.0,
left: 25.0,
right: 25.0,
),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25.0)),
elevation: 0.0,
child:
ListTile(
leading: Icon(Icons.delete_sweep, color: Colors.orangeAccent,),
title: Text(todoList[index],
),),
),
onDismissed: (direction){
if (direction == DismissDirection.endToStart) {
setState(() {
todoList.removeAt(index);
});// Закривається Сетстейт (")") і }
}
}, // Закривається ОнДісмісед
);
},
),
)
),
], // Закривається 1-ий чілдрен
),
);
}
submitData() {
setState(() {
todoList.add(temp);
clearText();
});
} // submit data
}
I tried many options to write the code but none of them worked.
Try this
List<String> todoList = [];
#override
void initState() {
super.initState();
myController.addListener(() {
setState(() {
submit = myController.text.isNotEmpty;
});
});
omLoadData();
}
submitData() async {
setState(() {
todoList.add(temp);
clearText();
});
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setStringList('todo_list', todoList);
}
omLoadData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final data = prefs.getStringList("todo_list");
todoList.addAll(data!);
}

Flutter - Variable in function available when building Widget

If I understood correctly (but clearly I don't) when you need a var available when you build the widget you need to call the function in the initState(). The function is 'void getDevices()'
I need var _documentsIds to build DropdownMenuItem.
var _documentsIds is docs ID from a query I make to FirebaseFirestore
How do I make _documentsIds available to be used in my Widget?
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
import 'package:safegaurd/constants.dart';
import 'package:flutter_time_picker_spinner/flutter_time_picker_spinner.dart';
import 'package:safegaurd/screens/log_in_page.dart';
import 'package:safegaurd/components/buttons_navigate.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'new_device_page.dart';
class DeviceSelectionPage extends StatefulWidget {
const DeviceSelectionPage({Key? key}) : super(key: key);
static const String id = 'device_selection_page';
#override
State<DeviceSelectionPage> createState() => _DeviceSelectionPageState();
}
class _DeviceSelectionPageState extends State<DeviceSelectionPage> {
final _auth = FirebaseAuth.instance;
User? loggedInUser;
final firestoreInstance = FirebaseFirestore.instance;
final String devices = 'devices';
List? _documentsIds;
bool showSpinner = false;
String? selectedValue;
final bool checkOne = false;
Color sDeviceAlways = Colors.white54;
Color sDeviceTime = Colors.white54;
FontWeight sDeviceAlwaysW = FontWeight.normal;
FontWeight sDeviceTimeW = FontWeight.normal;
#override
void initState() {
super.initState();
getCurrentUser();
getDevices();
}
void getCurrentUser() async {
try {
final user = await _auth.currentUser;
if (user != null) {
getDevices();
};
} catch (e) {
print(e);
}
}
void getDevices() async {
var firebaseUser = FirebaseAuth.instance.currentUser?.email;
print('firebaseUser: $firebaseUser');
var query = await firestoreInstance
.collection(devices)
.where('email', isEqualTo: '$firebaseUser')
.get();
var _documentsIds = query.docs.map((doc) => doc.id).toList();
print('_documentsIds: $_documentsIds');
}
#override
Widget build(BuildContext context) {
print('_documentsIds: $_documentsIds');
return Scaffold(
appBar: AppBar(
leading: null,
actions: [
IconButton(
onPressed: () {
_auth.signOut();
Navigator.pop(context);
},
icon: Icon(Icons.close))
],
title: const Text('Device Selection page'),
),
body: ModalProgressHUD(
inAsyncCall: showSpinner,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(
height: 40,
child: Text(
'SAFEGAURD',
style: kAppTextStyle,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 380,
padding: const EdgeInsets.symmetric(horizontal: 24.0),
decoration: BoxDecoration(
border: Border.all(
color: Colors.lightBlueAccent, width: 1.0),
borderRadius: kBorderRadius),
child: DropdownButtonHideUnderline(
child: DropdownButton(
hint: const Text(
'Safegaurd Devices',
style: TextStyle(color: Colors.white54, fontSize: 25),
),
style:
const TextStyle(color: Colors.orange, fontSize: 25),
borderRadius: kBorderRadius,
iconSize: 40,
elevation: 16,
onChanged: (value) {
setState(() {
selectedValue = value.toString();
setState(() {
selectedValue;
print(selectedValue);
});
});
},
value: selectedValue,
items: _documentsIds?.map((itemsList) {
return DropdownMenuItem<String>(
value: itemsList,
child: Text(itemsList),
);
}).toList(),
),
),
)
],
),
Row(
children: [
Buttons_Navigate(
colour: Colors.teal,
title: 'Save Settings',
onPressed: () {},
width: 200,
),
],
),
Row(
children: [
Buttons_Navigate(
colour: Colors.teal,
title: 'Claim new Device',
onPressed: () {
Navigator.pushNamed(context, NewDevicePage.id);
},
width: 200,
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Buttons_Navigate(
colour: Colors.orange,
title: 'Back',
onPressed: () {
Navigator.pushNamed(context, LogInPage.id);
},
width: 40)
],
)
],
)),
));
}
}
wall, you can use futureBuilder and show A CircularProgressBar until the query is done check the documentation here: FutureBuilder
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
import 'package:safegaurd/constants.dart';
//import 'package:flutter_time_picker_spinner/flutter_time_picker_spinner.dart';
import 'package:safegaurd/screens/log_in_page.dart';
import 'package:safegaurd/components/buttons_navigate.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'new_device_page.dart';
class DeviceSelectionPage extends StatefulWidget {
const DeviceSelectionPage({Key? key}) : super(key: key);
static const String id = 'device_selection_page';
#override
State<DeviceSelectionPage> createState() => _DeviceSelectionPageState();
}
class _DeviceSelectionPageState extends State<DeviceSelectionPage> {
final _auth = FirebaseAuth.instance;
User? loggedInUser;
final firestoreInstance = FirebaseFirestore.instance;
final String devices = 'devices';
List? _documentsIds;
bool showSpinner = false;
//bool _isSelected1 = false;
//bool _isSelected2 = false;
//DateTime _dateTime = DateTime.now();
String? selectedValue;
final bool checkOne = false;
Color sDeviceAlways = Colors.white54;
Color sDeviceTime = Colors.white54;
FontWeight sDeviceAlwaysW = FontWeight.normal;
FontWeight sDeviceTimeW = FontWeight.normal;
#override
void initState() {
super.initState();
getCurrentUser();
getDevices();
}
void getCurrentUser() async {
try {
final user = await _auth.currentUser;
if (user != null) {
getDevices();
};
} catch (e) {
print(e);
}
}
Future<List<dynamic>> getDevices() async {
var firebaseUser = FirebaseAuth.instance.currentUser?.email;
print('firebaseUser: $firebaseUser');
var query = await firestoreInstance
.collection(devices)
.where('email', isEqualTo: '$firebaseUser')
.get();
List<String> _documentsIds = query.docs.map((doc) => doc.id).toList();
print('_documentsIds: $_documentsIds');
return _documentsIds;
}
#override
Widget build(BuildContext context) {
print('_documentsIds: $_documentsIds');
return Scaffold(
appBar: AppBar(
leading: null,
actions: [
IconButton(
onPressed: () {
_auth.signOut();
Navigator.pop(context);
},
icon: Icon(Icons.close))
],
title: const Text('Device Selection page'),
),
body: ModalProgressHUD(
inAsyncCall: showSpinner,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(
height: 40,
child: Text(
'SAFEGAURD',
style: kAppTextStyle,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 380,
padding: const EdgeInsets.symmetric(horizontal: 24.0),
decoration: BoxDecoration(
border: Border.all(
color: Colors.lightBlueAccent, width: 1.0),
borderRadius: kBorderRadius),
child: DropdownButtonHideUnderline(
child: FutureBuilder<List> (
future: getDevices(),
builder: (BuildContext context, AsyncSnapshot<List> snapshot){
if (!snapshot.hasData) {
return const Text('Waiting Devices',style: TextStyle(color: Colors.white54, fontSize: 25));
} else {
return DropdownButton(
hint: const Text(
'Safegaurd Devices',
style: TextStyle(color: Colors.white54, fontSize: 25),
),
style:
const TextStyle(color: Colors.orange, fontSize: 25),
borderRadius: kBorderRadius,
iconSize: 40,
elevation: 16,
onChanged: (value) {
setState(() {
selectedValue = value.toString();
setState(() {
selectedValue;
print(selectedValue);
});
});
},
value: selectedValue,
items: snapshot.data?.map((_documentsIds) =>
DropdownMenuItem<String>(
value: _documentsIds,
child: Text(_documentsIds),
)
).toList(),
);
}
}
)
),
)
],
),
Row(
children: [
Buttons_Navigate(
colour: Colors.teal,
title: 'Save Settings',
onPressed: () {},
width: 200,
),
],
),
Row(
children: [
Buttons_Navigate(
colour: Colors.teal,
title: 'Claim new Device',
onPressed: () {
Navigator.pushNamed(context, NewDevicePage.id);
},
width: 200,
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Buttons_Navigate(
colour: Colors.orange,
title: 'Back',
onPressed: () {
Navigator.pushNamed(context, LogInPage.id);
},
width: 40)
],
)
],
)),
));
}

Provider not rebuilding on flutter

suddently from nowhere i came up with provider not re rendering my home page when it's updated. I've inspected it and it IS UPDATED. It has newer data when i change it in firebase but the UI won't re-render showing the new data. That's my code:
Main function
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:my_event_app/pages/HomePage/home_page.dart';
import 'package:my_event_app/pages/Login/login_page.dart';
import 'package:my_event_app/providers/User/user.dart';
import 'package:provider/provider.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => UserModel()),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
// is not restarted.
primarySwatch: Colors.blue,
),
home: const Wrapper(),
),
);
}
}
class Wrapper extends StatelessWidget {
const Wrapper({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.userChanges(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
User? user = snapshot.data;
if (user == null) {
return const LoginPage();
}
return StreamBuilder<DocumentSnapshot>(
stream: FirebaseFirestore.instance
.collection('users')
.doc(FirebaseAuth.instance.currentUser!.uid)
.snapshots(),
builder: (context, userSnapshot) {
if (userSnapshot.hasData) {
Provider.of<UserModel>(context, listen: true)
.fromJson(userSnapshot.data!.data());
return const HomePage();
}
return const Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
});
} else {
return const Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}
},
);
}
}
And this is the home page:
import 'package:flutter/material.dart';
import 'package:my_event_app/http/auth/user/sign_out.dart';
import 'package:my_event_app/pages/Create_Event/create_event_page.dart';
import 'package:my_event_app/pages/Onboarding/onboarding_page.dart';
import 'package:my_event_app/providers/User/user.dart';
import 'package:my_event_app/widgets/event_card_widget.dart';
import 'package:provider/provider.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
#override
Widget build(BuildContext context) {
return Consumer<UserModel>(builder: (context, user, child) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: const Icon(Icons.help_outline, color: Colors.black, size: 30),
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return const OnboardingPage();
}));
},
),
actions: [
IconButton(
icon: const Icon(
Icons.arrow_forward_ios_sharp,
color: Colors.black,
),
onPressed: () {
signOut();
},
),
],
elevation: 0,
backgroundColor: Colors.white,
),
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Container(
color: Colors.white,
padding: const EdgeInsets.all(16),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const CircleAvatar(
radius: 25,
backgroundImage: NetworkImage(
"https://cdnnmundo1.img.sputniknews.com/img/07e5/09/13/1116212032_100:0:1273:1173_1920x0_80_0_0_efb734331af13dfe11ff6d43293c60e2.png"),
),
Container(
height: 50,
width: 50,
decoration: BoxDecoration(
color: Colors.orange[400],
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
spreadRadius: 1,
blurRadius: 5,
offset: const Offset(0, 3),
),
],
),
child: Center(
child: IconButton(
color: Colors.white,
onPressed: () {
// Navigate to add event widget
Navigator.push(context,
MaterialPageRoute(builder: (context) {
return const CreateEventPage();
}));
},
icon: const Icon(Icons.add),
),
),
),
],
),
const SizedBox(height: 32),
SizedBox(
width: double.infinity,
child: Text('Welcome, ${user.name}',
style: const TextStyle(
fontSize: 28,
fontWeight: FontWeight.bold,
fontFamily: "Roboto")),
),
const SizedBox(height: 32),
Container(
padding: const EdgeInsets.all(16),
height: 100,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
spreadRadius: 1,
blurRadius: 5,
offset: const Offset(0, 3),
),
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Stack(alignment: Alignment.center, children: [
SizedBox(
height: 45,
width: 45,
child: CircularProgressIndicator(
valueColor:
AlwaysStoppedAnimation(Colors.orange[400]),
value: 14 / 20,
semanticsValue: "14/20",
color: Colors.black,
),
),
const Text("78%",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
fontFamily: "Roboto")),
]),
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text("Weekly progress",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
)),
Text("14/20 tasks completed"),
],
),
const Icon(Icons.bar_chart),
],
),
),
Container(
margin: const EdgeInsets.symmetric(vertical: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: const [
Text("You have 5 tasks for today",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
)),
Icon(Icons.calendar_today_outlined)
],
),
),
_renderEvents(user),
],
),
),
),
);
});
}
}
Column _renderEvents(UserModel user) {
return Column(
children: [
for (var event in user.events)
EventCard(
eventId: event,
),
],
);
}
And here's the provider:
import 'package:flutter/material.dart';
class UserModel extends ChangeNotifier {
String _name = '';
String _surnames = '';
String _uid = '';
String _email = '';
List<dynamic> _events = [];
String get name => _name;
String get surnames => _surnames;
String get uid => _uid;
String get email => _email;
List<dynamic> get events => _events;
UserModel();
set name(String value) {
_name = value;
notifyListeners();
}
set surnames(String value) {
_surnames = value;
notifyListeners();
}
set uid(String value) {
_uid = value;
notifyListeners();
}
set email(String value) {
_email = value;
notifyListeners();
}
set events(List<dynamic> value) {
_events = value;
notifyListeners();
}
void addEvent(String event) {
_events.add(event);
notifyListeners();
}
void removeEvent(String event) {
_events.remove(event);
notifyListeners();
}
void updateUser(String name, String uid) {
name = name;
uid = uid;
notifyListeners();
}
void clearUser() {
_name = '';
_uid = '';
notifyListeners();
}
Map<String, dynamic> toJson() {
return {
'name': _name,
'surnames': _surnames,
'uid': _uid,
'email': _email,
'events': _events
};
}
fromJson(Object? json) {
try {
Map<dynamic, dynamic> map = json as Map<dynamic, dynamic>;
_name = map['name'];
_surnames = map['surnames'];
_uid = map['uid'];
_email = map['email'];
_events = map['events'];
} catch (e) {
print(e);
}
}
}
```
As you can see i use Consumer in order to read data and i have a change notifier in the begginig, but it won't re render and show for example new name if i change it in fireabase.
Thank you so much!
You are using fromJson method to update values in UserModel, but it does not call notifyListeners. Add notifyListeners(); to the end of this method:
fromJson(Object? json) {
try {
Map<dynamic, dynamic> map = json as Map<dynamic, dynamic>;
_name = map['name'];
_surnames = map['surnames'];
_uid = map['uid'];
_email = map['email'];
_events = map['events'];
notifyListeners(); // add this
} catch (e) {
print(e);
}
}
Also some other things:
Consider declaring class UserModel with ChangeNotifier instead of class UserModel extends ChangeNotifier.
fromJson methods usually are acting as factory methods, meaning these return a new instance, and don't set members in an existing instance.
Instead of Provider.of<UserModel>(context, listen: true).fromJson(userSnapshot.data!.data()); you can try: context.read<UserModel>().fromJson(userSnapshot.data!.data());. Here you don't really need listening, you just want to find the provider and call fromJson. Your Consumer is the one which is listening to the changes accordingly.

How to select multiple checkboxes in flutter in checkboxlisttile

Can anyone please tell me how do I select multiple options in checkboxlisttile.
Here I am able to click only one option. I want to set the status column in note table in database as completed when i check the particular item.
(Actually I want to select the item as completed and display it under another tab called completed. checkboxlisttile is created dynamically i.e from database. When a new note is added it is displayed in this listview.)
note_info.dart //this is the screen where notes are displayed i.e listview
import 'dart:io';
import 'package:vers2cts/models/note_model.dart';
import 'package:vers2cts/models/customer_model.dart';
import 'package:vers2cts/services/db_service.dart';
import 'package:vers2cts/utils/db_helper.dart';
import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'new_note.dart';
class Note_Info extends StatefulWidget{
final String appBarTitle;
final CustomerModel customer;
//Note_Info();
Note_Info(this. customer, this.appBarTitle);
#override
State<StatefulWidget> createState() {
//return Note_InfoState();
return Note_InfoState(this. customer,this.appBarTitle);
}
}
class Note_InfoState extends State<Note_Info> {
DBService dbService = DBService();
List<NoteModel> noteList;
int count = 0;
static final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
NoteModel note=NoteModel();
String appBarTitle;
CustomerModel customer=new CustomerModel();
Note_InfoState(this.customer, this.appBarTitle);
bool rememberMe = false;
DateTime _date = DateTime.now();
TextEditingController custfNameController = TextEditingController();
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
updateListView();
if (noteList == null) {
noteList = List<NoteModel>();
updateListView();
}
TextStyle titleStyle = Theme.of(context).textTheme.subhead;
var height = MediaQuery.of(context).size.height;
var name=customer.first_name+" "+customer.last_name;
custfNameController.text = name;
return DefaultTabController(
length: 4,
child: Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: Icon(
Icons.add,
),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => NewNote(customer,note)));
},
)
],
),
body: Container(
child: Column(
children: <Widget>[
TextField(controller: custfNameController,
style: TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold),
textAlign: TextAlign.center),
Padding(
padding: const EdgeInsets.all(15.0),
child: Row(children: [
ImageProfile(customer.cust_photo),
Padding(
padding: const EdgeInsets.only(left: 30.0),
child: IconButton(
icon: Icon(
Icons.call,
color: Colors.green,
size: 45,
),
onPressed: () {
},
),
),
],),
),
SizedBox(
height: 50,
child: AppBar(
bottom: TabBar(
tabs: [
Tab(
text: "All",
),
Tab(
text: "Pending",
),
Tab(
text: "Cancelled",
),
Tab(
text: "Completed",
),
],
),
),
),
// create widgets for each tab bar here
Expanded(
child: TabBarView(
children: [
// first tab bar view widget
Container(
child: getNotecheckList()
),
// second tab bar view widget
Container(
),
Container(
child: Center(
child: Text(
'Cancelled',
),
),
),
Container(
child: Center(
child: Text(
'Completed',
),
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 55.0,
width: 200,
child: RaisedButton(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
color: Theme
.of(context)
.primaryColorDark,
textColor: Colors.white,
child: Text('Save', textScaleFactor: 1.5,),
onPressed: () {
setState(() {
//_reset();
});
},
),
),
),
]
),
)
));
}
Widget ImageProfile(String fileName) {
return Center(
child: CircleAvatar(
radius: 80.0,
backgroundImage: fileName == null
?AssetImage('images/person_icon.jpg')
:FileImage(File(customer.cust_photo))),
);
}
Future<void> updateListView() {
final Future<Database> dbFuture = DB.init();
dbFuture.then((database) {
int cid=customer.cust_id;
Future<List<NoteModel>> noteListFuture = dbService.getCustomerNotes(cid);
noteListFuture.then((noteList) {
setState(() {
this.noteList = noteList;
this.count = noteList.length;
});
});
});
}
int _isChecked=-1;
ListView getNotecheckList() {
return ListView.builder(
itemCount: count,
itemBuilder: (BuildContext context, int position) {
return Card(
color: Colors.white,
elevation: 2.0,
child: CheckboxListTile(
title: Text(this.noteList[position].note),
subtitle: Text(this.noteList[position].actn_on),
//secondary: const Icon(Icons.web),
value: position== _isChecked,
onChanged: (bool value) {
setState(() {
_isChecked = value?position:-1;
});
},
controlAffinity: ListTileControlAffinity.leading,
),
);
},
);
}
}
new_note.dart //this is where new note is added.
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:smooth_star_rating/smooth_star_rating.dart';
import 'package:intl/intl.dart';
import 'package:vers2cts/models/customer_model.dart';
import 'package:vers2cts/models/note_model.dart';
import 'package:vers2cts/services/db_service.dart';
import 'package:vers2cts/utils/form_helper.dart';
class NewNote extends StatefulWidget{
final NoteModel note;
final CustomerModel customer;
NewNote(this.customer,this. note);
//Dropdown
/*
final String label;
final Function(Color) onChanged;
final double height;
final double width;
NewNote.fordropdwn({
Key key,
this.onChanged,
this.height = 25,
this.width = 150,
this.label,
}) : super(key: key);*/
#override
State<StatefulWidget> createState() {
//return New_NoteState(this.customer);
return New_NoteState(this.customer,this.note);
}
}
class New_NoteState extends State<NewNote> with SingleTickerProviderStateMixin{
New_NoteState(this.customer,this.note);
NoteModel note=new NoteModel();
CustomerModel customer=new CustomerModel();
TextEditingController NoteController=TextEditingController();
TextEditingController custfNameController = TextEditingController();
DateTime _reminderDate = DateTime.now();
DBService dbService=new DBService();
SpeedDial _speedDial(){
return SpeedDial(
// child: Icon(Icons.add),
animatedIcon: AnimatedIcons.add_event,
animatedIconTheme: IconThemeData(size: 24.0),
backgroundColor: Colors.yellow,
curve: Curves.easeInCirc,
children: [
SpeedDialChild(
child: Icon(Icons.location_on,color: Colors.yellow,),
//backgroundColor: Theme.of(context).primaryColor,
label: 'Add Location',
//labelBackgroundColor:Theme.of(context).primaryColor,
),
SpeedDialChild(
child: Icon(Icons.keyboard_voice),
//backgroundColor: Colors.yellow,
label: 'Add voice',
//labelBackgroundColor: Colors.yellow
),
SpeedDialChild(
child: Icon(Icons.attachment_outlined,color :Colors.redAccent),
//backgroundColor:Theme.of(context).primaryColorLight,
label: 'Add File',
// labelBackgroundColor: Theme.of(context).primaryColorLight
),
SpeedDialChild(
child: Icon(Icons.image,color: Colors.lightBlue,),
//backgroundColor: Colors.yellow,
label: 'Add Image',
// labelBackgroundColor: Colors.yellow,
),
],
);
}
//for DropDownMenu
Color value=Colors.red;
final List<Color> colors = [
Colors.red,
Colors.blue,
Colors.green,
Colors.yellow,
Colors.pink,
Colors.purple,
Colors.brown,
];
//for Switch
bool isSwitched = false;
var textValue = 'Switch is OFF';
void toggleSwitch(bool value) {
if(isSwitched == false)
{
setState(() {
isSwitched = true;
note.rmnd_ind=1;
//this.note.remindOn = _reminderDate.toString();
});
}
else
{
setState(() {
isSwitched = false;
note.rmnd_ind=0;
});
}
}
#override
Widget build(BuildContext context) {
var height = MediaQuery.of(context).size.height;
var width = MediaQuery.of(context).size.width;
var name=customer.first_name+customer.last_name;
custfNameController.text = name;
return WillPopScope(
onWillPop: () {
// Write some code to control things, when user press Back navigation button in device navigationBar
moveToLastScreen();
},
child: Scaffold(
appBar:AppBar(),
body:ListView(
children: <Widget>[
SizedBox(
height: 2.0,
),
TextField(controller: custfNameController,
style: TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold),
textAlign: TextAlign.center),
Align(
alignment: Alignment.centerLeft,
child: Text("Add New",textAlign: TextAlign.left,
style: TextStyle(fontSize: 22,fontWeight: FontWeight.bold),),
),
SizedBox(
height: 2.0,
),
Divider(),
SizedBox(
height: 2.0,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: NoteController,
decoration: InputDecoration(
border: OutlineInputBorder(
borderSide: const BorderSide(width: 2.0),)),
keyboardType: TextInputType.multiline,
minLines: 5,//Normal textInputField will be displayed
maxLines: 5, // when user presses enter it will adapt to it
onChanged: (value) {
this.note.note = value;
},
),
),
TableCalendar(
selectedDayPredicate: (day) {
return isSameDay(_reminderDate, day);
},
onDaySelected: (selectedDay, focusedDay) {
setState(() {
String _reminderDate = DateFormat('dd-MM-yyyy').format(selectedDay);
note.actn_on=_reminderDate.toString();
});
},// Set initial date
focusedDay: DateTime.now(),
firstDay: DateTime.utc(2010, 10, 16),
lastDay: DateTime.utc(2030, 3, 14),),
SizedBox(
height: height*0.03,
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Row(//mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text("Remind me",style: TextStyle(fontSize: 20),),
Padding(
padding: const EdgeInsets.only(left:80.0),
child: Container(
child: Switch(
onChanged: toggleSwitch,
value: isSwitched,
//activeColor: Colors.blue,
//activeTrackColor: Colors.yellow,
//inactiveThumbColor: Colors.redAccent,
//inactiveTrackColor: Colors.orange,
),
),
),
],),
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Row(mainAxisAlignment: MainAxisAlignment.start,
children:<Widget>[
Text("Priority",style: TextStyle(fontSize: 20.0),),
Padding(
padding: const EdgeInsets.only(left:20.0),
child: Container(
child: SmoothStarRating(
size: height=50.0,
allowHalfRating: false,
onRated: (value) {
this.note.prty=value;
print("rating value -> $value");
},
),
),
)]),
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Row(mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text("Color",style: TextStyle(fontSize: 20),),
Padding(
padding: const EdgeInsets.only(left:80.0),
child: Container(
child: DropdownButton<Color>(
value: value,
//hint: Text(widget.label ?? ''),
onChanged: (color) {
setState(() => value = color);
//widget.onChanged(color);
},
items: colors.map((e) => DropdownMenuItem(
value: e,
child: Container(
// width: 60.0,
//height: 10.0,
width: 60.0,
// height: widget.height,
color: e,
),
),
)
.toList(),
),
),
),
],),
),
SizedBox(
height: height*0.08,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 55.0,
width: 200,
child: RaisedButton(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
color: Theme.of(context).primaryColorDark,
textColor: Colors.white,
child: Text('Save',textScaleFactor: 1.5,),
onPressed: (){
setState(() {
_save();
});
},
),
),
),
],
),
floatingActionButton:_speedDial(),
));
}
void moveToLastScreen() {
Navigator.pop(context, true);
}
void _save() async {
moveToLastScreen();
note.cust_id=customer.cust_id;
print(customer.cust_id);
print(note.cust_id);
int result;
if (note.note_id != null) { // Case 1: Update operation
result = await dbService.updateNote(note);
} else { // Case 2: Insert Operation
result = await dbService.insertNote(note);
}
if (result != 0) { // Success
FormHelper.showAlertDialog(context,'Status', 'Note Saved Successfully');
} else { // Failure
FormHelper.showAlertDialog(context,'Status', 'Problem Saving Note');
}
}
}
db_service.dart
import 'package:vers2cts/models/customer_model.dart';
import 'package:vers2cts/models/languages_model.dart';
import 'package:vers2cts/models/note_model.dart';
import 'package:vers2cts/models/user_model.dart';
import 'package:vers2cts/utils/db_helper.dart';
class DBService {
Future<int> insertNote(NoteModel note) async {
await DB.init();
var result = await DB.insert(NoteModel.table, note);
return result;
}
Future<List<NoteModel>> getCustomerNotes(int customer) async {
await DB.init();
var res = await DB.rawQuery("note WHERE cust_id = '$customer'");
int count = res.length;
List<NoteModel> notelist = List<NoteModel>();
// For loop to create a 'Note List' from a 'Map List'
for (int i = 0; i < count; i++) {
notelist.add(NoteModel.fromMap(res[i]));
}
return notelist;
}
}
note_model.dart
import 'model.dart';
class NoteModel extends Model {
static String table = 'note';
bool isSelected=false;
int note_id;
int cust_id;
String note;
String actn_on;
int rmnd_ind;
double prty;
String colr;
String sts;
int id;
String cre_date;
String cre_by;
String mod_date;
String mod_by;
int txn_id;
int delete_ind;
NoteModel({
this.note_id,
this.cust_id,
this.note,
this.actn_on,
this.rmnd_ind,
this.prty,
this.colr,
this.sts,
this.id,
this.cre_date,
this.cre_by,
this.mod_date,
this.mod_by,
this.txn_id,
this.delete_ind
});
static NoteModel fromMap(Map<String, dynamic> map) {
return NoteModel(
note_id: map["note_id"],
cust_id: map['cust_id'],
note: map['note'].toString(),
actn_on: map['actn_on'].toString(),
rmnd_ind: map['rmnd_ind'],
prty: map['prty'],
colr: map['colr'].toString(),
sts: map['sts'].toString(),
id: map['id'],
cre_date: map['cre_date'].toString(),
cre_by: map['cre_by'].toString(),
mod_date: map['mod_date'].toString(),
mod_by: map['mod_by'].toString(),
txn_id: map['txn_id'],
delete_ind: map['delete_ind'],
);
}
Map<String, dynamic> toMap() {
Map<String, dynamic> map = {
'note_id': note_id,
'cust_id': cust_id,
'note':note,
'actn_on': actn_on,
'rmnd_ind': rmnd_ind,
'prty': prty,
'colr': colr,
'sts':sts,
'id': id,
'cre_date': cre_date,
'cre_by': cre_by,
'mod_date':mod_date,
'mod_by':mod_by,
'txn_id':txn_id,
'delete_ind': delete_ind
};
if (note_id != null) {
map['note_id'] = note_id;
}
return map;
}
}
db_helper.dart
import 'dart:async';
import 'package:vers2cts/models/model.dart';
import 'package:path/path.dart' as p;
import 'package:sqflite/sqflite.dart';
abstract class DB {
static Database _db;
static int get _version => 1;
static Future<Database> init() async {
if (_db != null) {
return _db;
}
try {
var databasesPath = await getDatabasesPath();
String _path = p.join(databasesPath, 'CTS.db');
_db = await openDatabase(_path, version: _version, onCreate: onCreate);
print('db location:'+_path);
} catch (ex) {
print(ex);
}
}
static void onCreate(Database db, int version) async {
await db.execute(
'CREATE TABLE note (note_id INTEGER PRIMARY KEY,cust_id INTEGER, '
'note TEXT, '
'actn_on TEXT, rmnd_ind INTEGER, prty REAL, colr TEXT,'
'sts TEXT,'
'id INTEGER, cre_date TEXT,cre_by TEXT, mod_date TEXT,mod_by TEXT, txn_id INTEGER, delete_ind INTEGER)');
}
static Future<List<Map<String, dynamic>>> query(String table) async =>
_db.query(table);
static Future<int> insert(String table, Model model) async =>
await _db.insert(table, model.toMap());
static Future<Batch> batch() async => _db.batch();
static Future<List<Map<String, dynamic>>> rawQuery(String table) async =>
_db.query(table);
}
You need to store what all values are selected from user and then play with it.
For example -
var selectedIndexes = [];
ListView getNotecheckList() {
return ListView.builder(
itemCount: count,
itemBuilder: (_, int index) {
return Card(
color: Colors.white,
elevation: 2.0,
child: CheckboxListTile(
title: Text(this.noteList[position].note),
subtitle: Text(this.noteList[position].actn_on),
value: selectedIndexes.contains(index),
onChanged: (_) {
if (selectedIndexes.contains(index)) {
selectedIndexes.remove(index); // unselect
} else {
selectedIndexes.add(index); // select
}
},
controlAffinity: ListTileControlAffinity.leading,
),
);
},
);
}
store only index or whole array and play around
Output :-
Code :-
import 'package:flutter/material.dart';
class CheckBoxExample extends StatefulWidget {
const CheckBoxExample({Key? key}) : super(key: key);
#override
State<CheckBoxExample> createState() => _CheckBoxExampleState();
}
class _CheckBoxExampleState extends State<CheckBoxExample> {
List multipleSelected = [];
List checkListItems = [
{
"id": 0,
"value": false,
"title": "Sunday",
},
{
"id": 1,
"value": false,
"title": "Monday",
},
{
"id": 2,
"value": false,
"title": "Tuesday",
},
{
"id": 3,
"value": false,
"title": "Wednesday",
},
{
"id": 4,
"value": false,
"title": "Thursday",
},
{
"id": 5,
"value": false,
"title": "Friday",
},
{
"id": 6,
"value": false,
"title": "Saturday",
},
];
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 64.0),
child: Column(
children: [
Column(
children: List.generate(
checkListItems.length,
(index) => CheckboxListTile(
controlAffinity: ListTileControlAffinity.leading,
contentPadding: EdgeInsets.zero,
dense: true,
title: Text(
checkListItems[index]["title"],
style: const TextStyle(
fontSize: 16.0,
color: Colors.black,
),
),
value: checkListItems[index]["value"],
onChanged: (value) {
setState(() {
checkListItems[index]["value"] = value;
if (multipleSelected.contains(checkListItems[index])) {
multipleSelected.remove(checkListItems[index]);
} else {
multipleSelected.add(checkListItems[index]);
}
});
},
),
),
),
const SizedBox(height: 64.0),
Text(
multipleSelected.isEmpty ? "" : multipleSelected.toString(),
style: const TextStyle(
fontSize: 22.0,
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
],
),
),
);
}
}