List of text in one Card using ListView.builder twice and for loop? - flutter

With my current code, my list is put into separate cards. I need it to be in one. I'm using two ListView.builders and a loop. I believe that's what's causing the problem. Please tell me if I'm wrong.
Every time the user taps submit on my second TextField a new TextField appears, functionality I would like to keep one way or another.
I'm just staring out so any help if appreciated.
My end goal is to have a bullet point list but the bullet points aren't important right now.
Here's my code:
class PostNote extends StatefulWidget {
User user;
PostNote({
required this.user,
});
#override
State<PostNote> createState() => _PostNoteState();
}
class _PostNoteState extends State<PostNote> {
FirebaseFirestore firestore = FirebaseFirestore.instance;
TextEditingController titleController = TextEditingController();
final List<TextField> _textFields = [];
final List<TextEditingController> _controllers = [];
bool loading = false;
#override
void initState() {
super.initState();
_addTextField();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Color(0xFF162242),
elevation: 0,
),
body: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(20),
child: Column(
children: [
Text(
"Title",
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
SizedBox(
height: 15,
),
Container(
height: 60,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(10),
),
color: Colors.white,
),
padding: EdgeInsets.only(left: 10, right: 10),
child: TextField(
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
),
),
textInputAction: TextInputAction.next,
style: TextStyle(
color: Color(0xFF192A4F),
fontSize: 18,
),
controller: titleController,
autofocus: true,
),
),
SizedBox(
height: 30,
),
Text(
"Notes",
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
SizedBox(
height: 15,
),
Container(
padding: EdgeInsets.only(left: 10, right: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(10),
),
color: Colors.white,
),
child: ListView.builder( // HERE
shrinkWrap: true,
itemCount: _textFields.length,
itemBuilder: (_, index) {
return _textFields[index];
},
),
),
SizedBox(
height: 50,
),
loading
? Center(
child: CircularProgressIndicator(),
)
: Container(
height: 50,
width: MediaQuery.of(context).size.width,
child: ElevatedButton(
child: Text(
"Add Note",
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Color(0xFF162242)),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
),
onPressed: () async {
for (var notesController in _controllers) // HERE {
if (titleController.text == "" ||
notesController.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content:
Text("All fields are required")));
} else {
setState(() {
loading = true;
});
await FirestoreServiceEdit().insertNote(
titleController.text,
notesController.text,
widget.user.uid);
CollectionReference notes =
firestore.collection('notes');
QuerySnapshot allResults = await notes.get();
allResults.docs.forEach((DocumentSnapshot result) {
print(result.data());
});
if (!mounted) return;
setState(() {
loading = false;
});
Navigator.pop(context);
}
}
}),
),
]),
),
),
),
);
}
void _addTextField() {
final notesController = TextEditingController();
_textFields.add(
TextField(
decoration: InputDecoration(
prefix: Icon(
Icons.circle,
size: 8,
color: Colors.black,
),
),
autofocus: true,
controller: notesController,
onSubmitted: (_) => setState(() => _addTextField()),
),
);
_controllers.add(notesController);
}
}
class FirestoreServiceEdit{
FirebaseFirestore firestore = FirebaseFirestore.instance;
Future insertNote(String title, String notes, String? userId,)async{
try{
await firestore.collection('notes').add({
"title":title,
"notes":notes,
"userId":userId
});
} catch (e) {}
}
}
class NoteModelEdit {
String id;
String title;
String notes;
String userId;
NoteModelEdit({
required this.id,
required this.title,
required this.notes,
required this.userId
});
factory NoteModelEdit.fromJson(DocumentSnapshot snapshot){
return NoteModelEdit(
id: snapshot.id,
title: snapshot['title'],
notes: snapshot['notes'],
userId: snapshot['userId']
);
}
}
Home screen:
body: StreamBuilder(
stream: FirebaseFirestore.instance
.collection("notes")
.where('userId', isEqualTo: user.uid)
.snapshots(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
if (snapshot.data.docs.length > 0) {
return ListView.builder( // HERE
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index) {
NoteModelEdit note =
NoteModelEdit.fromJson(snapshot.data.docs[index]);
return Card(
margin: EdgeInsets.only(top: 18, left: 15, right: 15),
child: Column(children: [
ListTile(
title: Center(
child: Container(
padding: EdgeInsets.only(bottom: 10),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(width: 0.5),
),
),
child: Text(
note.title,
textWidthBasis: TextWidthBasis.longestLine,
style: TextStyle(
fontSize: 40,
fontWeight: FontWeight.w600),
textAlign: TextAlign.center,
),
),
),
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => EditNoteScreen(),
));
},
),
SizedBox(
height: 15,
),
Align(
alignment: Alignment.centerLeft,
child: Text(
note.notes,
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.w700),
),
),
SizedBox(
height: 15,
),
]),
);
});
Thank you for your time!

You will need to augment your logic to look at all the TextFields at the same time rather than one at a time and inserting a note for each.
if (titleController.text.isEmpty ||
_controllers.any((element) => element.text.isEmpty)) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content:
Text("All fields are required")));
} else {
setState(() {
loading = true;
});
}
await FirestoreServiceEdit().insertNote(
titleController.text,
_controllers.map((element) => element.text).join("\n"),
widget.user.uid);

you can do like this :
Widget listInCard() {
List testList = ["note1", "note2", "note3"];
return Card(
color: Colors.blue.shade200,
elevation: 5,
child: ListView.builder(
itemCount: testList.length,
itemBuilder: (context, index) {
return Text(testList[index]);
}),
);
}
The blue color is the Card and inside it, it is a list of notes.
You can also use Container instead of Card.

Related

How to pass a variable (TextEditingController) to another class

class that i have the variable in
...
class _ActivitiesParticipantsState extends State<ActivitiesParticipants> {
final activityController = TextEditingController();
final user = FirebaseAuth.instance.currentUser!;
//Activities participants
List<String> docIDs = [];
//get docIDS
Future getDocId() async {
await FirebaseFirestore.instance
.collection(
activityController.text.trim(),
)
.get()
.then(
(snapshot) => snapshot.docs.forEach(
(element) {
docIDs.add(element.reference.id);
},
),
);
//stuff
}
#override
void dispose() {
activityController.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 30, horizontal: 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextFormField(
controller: activityController,
decoration: InputDecoration(
labelText: 'e',
border: InputBorder.none,
),
),
GestureDetector(
onTap: () async {
setState(
() {
getDocId();
},
);
},
child: Container(
padding: EdgeInsets.all(
20,
),
decoration: BoxDecoration(
color: Colors.deepPurple,
borderRadius: BorderRadius.circular(12),
),
child: Center(
child: Text(
'Test',
style: TextStyle(
color: Colors.white,
fontFamily: 'Quicksand',
fontWeight: FontWeight.w600,
fontSize: 18,
),
),
),
),
),
Expanded(
child: FutureBuilder(
builder: (context, snapshot) {
return ListView.builder(
itemCount: wee(),
//docIDs.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 15),
child: ListTile(
dense: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8)),
tileColor: Color.fromARGB(255, 235, 235, 235),
title: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10, vertical: 20),
child: Column(
children: [
SizedBox(
height: 5,
),
Align(
alignment: Alignment.centerLeft,
child: Title(
color: Colors.black,
child: InterestedName(
documentID: docIDs[index]),
),
),
SizedBox(
height: 20,
),
],
),
),
),
);
},
);
},
),
),
],
),
),
),
);
}
}
...
How do I get the variable "activityController" to another class?
This other class is used to get Text to fill the ListTile
class that I want to get the variable
final String documentID;
InterestedName({required this.documentID});
#override
Widget build(BuildContext context) {
// get the collection
CollectionReference users = FirebaseFirestore.instance.collection('Project Koalas [test]');
return FutureBuilder<DocumentSnapshot>(
future: users.doc(documentID).get(),
builder: ((context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
Map<String, dynamic> data =
snapshot.data!.data() as Map<String, dynamic>;
return Text(
'Name: ${data['name']}',
style: TextStyle(
fontSize: 16,
fontFamily: 'Quicksand',
fontWeight: FontWeight.w600),
);
}
return Text('loading...');
}),
);
}
}
I would like to get the variable to be able to get the collection name that I want to take data from, as the collection I would like to take from is dependent on the user's choice.
If there is any way else to somehow fill the List tile in the same class, please let me know how.
Any help appreciated!

Tab Bar in Flutter

I want to implement Tab Bar in my application having length 2 named "Need Help" and "Help Requests". In "Need Help" tab, I want my first container (i.e. Upload data to Firestore Database) and in "Help Requests" tab, I want my second container (i.e. Retrieve data from Firestore Database). I am new to flutter and will be very much grateful to you if you can help me.
Source code:
import 'package:chat_app/group_chats/group_info.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import '../constants.dart';
import '../global_data.dart';
class FinancialRoom extends StatelessWidget {
final String groupChatId, groupName;
FinancialRoom({required this.groupName, required this.groupChatId, Key? key})
: super(key: key);
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
final FirebaseAuth _auth = FirebaseAuth.instance;
final _formKey = GlobalKey<FormState>();
TextEditingController amountValue = TextEditingController();
void onSend() async {
Map<String, dynamic> data = {
"amount": amountValue.text,
"sendBy": _auth.currentUser!.displayName,
"type": "text",
"time": FieldValue.serverTimestamp(),
};
amountValue.clear();
await _firestore
.collection('groups')
.doc(groupChatId)
.collection('chats')
.add(data);
}
#override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
title: Text(groupName),
actions: [
IconButton(
onPressed: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => GroupInfo(
groupName: groupName,
groupId: groupChatId,
),
),
),
icon: Icon(Icons.more_vert)),
],
),
body: SafeArea(
child: ListView(padding: EdgeInsets.all(20.0), children: [
Container(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(
height: 10.0,
),
TextFormField(
controller: amountValue,
decoration: InputDecoration(
hintText: 'Enter the amount you want',
labelText: 'Enter the amount you want',
prefixIcon: Icon(Icons.account_balance_wallet_outlined),
enabledBorder: kEnabledBorder,
focusedBorder: kFocusedBorder,
errorBorder: kErrorBorder,
focusedErrorBorder: kErrorBorder,
),
onTap: () {
},
// The validator receives the text that the user has entered.
validator: (value) {
if (value!.isEmpty) {
return 'Please enter the amount you want';
}
return null;
},
),
SizedBox(
height: kInputSpacing,
),
SizedBox(
width: double.infinity,
child: FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
color: Colors.blue,
textColor: Colors.white,
padding: EdgeInsets.only(top: 16.0, bottom: 16.0),
onPressed: onSend,
child: Text(
'SEND',
style: kButtonTextStyle,
),
),
),
],
),
),
Container(
height: size.height / 1.27,
width: size.width,
child: StreamBuilder<QuerySnapshot>(
stream: _firestore
.collection('groups')
.doc(groupChatId)
.collection('chats')
.orderBy('time')
.snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) {
Map<String, dynamic> data =
snapshot.data!.docs[index].data()
as Map<String, dynamic>;
return messageTile(size, data);
},
);
} else {
return Container();
}
},
),
),
]),
),
);
}
Widget messageTile(Size size, Map<String, dynamic> data) {
return Builder(builder: (_) {
if (data['type'] == "text") {
return Container(
width: size.width,
alignment: data['sendBy'] == _auth.currentUser!.displayName
? Alignment.centerRight
: Alignment.centerLeft,
child: Container(
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 14),
margin: EdgeInsets.symmetric(vertical: 5, horizontal: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.blue,
),
child: Column(
children: [
Text(
data['sendBy'],
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w500,
color: Colors.white,
),
),
SizedBox(
height: size.height / 200,
),
Text(
data['amount'],
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.white,
),
),
],
)),
);
} else if (data['type'] == "img") {
return Container(
width: size.width,
alignment: data['sendBy'] == _auth.currentUser!.displayName
? Alignment.centerRight
: Alignment.centerLeft,
child: Container(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 14),
margin: EdgeInsets.symmetric(vertical: 5, horizontal: 8),
height: size.height / 2,
child: Image.network(
data['amount'],
),
),
);
} else if (data['type'] == "notify") {
return Container(
width: size.width,
alignment: Alignment.center,
child: Container(
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8),
margin: EdgeInsets.symmetric(vertical: 5, horizontal: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Colors.black38,
),
child: Text(
data['message'],
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
);
} else {
return SizedBox();
}
});
}
}
It's very straightforward to implement a simple TabBar in your app. All you need is a TabController and two widgets called TabBar and TabBarView. Here is a simple example:
DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(tabs: [
Tab(text: 'Tab 1'),
Tab(text: 'Tab 2'),
]),
),
body: TabBarView(children: [
// Tab 1
Container(color: Colors.red),
// Tab 2
Container(color: Colors.blue),
]),
),
);
Now all you need to do is to replace children inside TabBarView with whatever you want to display.

type '(dynamic) => Null' is not a subtype of 'TextEditingController?'

I've been trying to accept user input in an extracted TextFormField method(Name, contact and email) and then save them to my firestore database using TextEditingController.
Here lies the case after accepting the input, the name and email controller always displays the same input. After saving, even for test purposes, the database always shows that only null values have been returned from the controllers...
Please help me solve this problem...
Snippet of the code:
class Profile extends StatefulWidget {
final String email;
Profile({Key key, this.email}) : super(key: key);
get user => AuthService();
#override
_ProfileState createState() => _ProfileState(email);
}
class _ProfileState extends State<Profile> {
String email;
String contain;
_ProfileState(this.email);
bool showPhone = false;
//Text editing controller
final TextEditingController _emailController = TextEditingController();
final TextEditingController _phoneController = TextEditingController();
final TextEditingController _nameController = TextEditingController();
// initState
#override
void initState() {
super.initState();
_emailController.addListener(() {
final String text = _emailController.text;
_emailController.value = _emailController.value.copyWith(
text: text,
selection:
TextSelection(baseOffset: text.length, extentOffset: text.length),
composing: TextRange.empty,
);
});
_phoneController.addListener(() {
final String contact = _phoneController.text;
_phoneController.value = _phoneController.value.copyWith(
text: contact,
selection: TextSelection(
baseOffset: contact.length,
extentOffset: contact.length,
),
composing: TextRange.empty,
);
});
_nameController.addListener(() {
final String contact = _nameController.text;
_nameController.value = _nameController.value.copyWith(
text: contact,
selection: TextSelection(
baseOffset: contact.length,
extentOffset: contact.length,
),
composing: TextRange.empty,
);
});
}
#override
void dispose() {
// Clean up the controller when the widget is removed from the
// widget tree.
_emailController.dispose();
_phoneController.dispose();
_nameController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
final FirebaseAuth _auth = FirebaseAuth.instance;
bool loading = false;
final _formKey = GlobalKey<FormState>();
final doc = Database();
final ThemeData themeData = Theme.of(context);
String name, email, contact;
return loading
? Loading()
: SafeArea(
child: StreamBuilder<UserData>(
stream: Database(uid: doc.uid).userData,
builder: (context, snapshot) {
if (snapshot.hasData) {
UserData userData = snapshot.data;
return Scaffold(
appBar: AppBar(
backgroundColor: Aqua,
elevation: 1,
title: Text(
'Edit Profile Info',
style: themeData.textTheme.headline1.copyWith(
color: White,
fontSize: 22,
letterSpacing: 0.75,
),
),
),
body: new Container(
height: window.physicalSize.height * 0.85,
padding: const EdgeInsets.only(
left: 16,
right: 16,
top: 25,
),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
new Center(
child: new Stack(
children: [
addVertical(20),
Container(
width: 190,
height: 190,
decoration: BoxDecoration(
border: Border.all(
width: 5,
color: Theme.of(context)
.scaffoldBackgroundColor,
),
boxShadow: [
BoxShadow(
blurRadius: 15,
spreadRadius: 5,
color: Cyan.withOpacity(0.5),
offset: Offset(0, 15),
),
],
shape: BoxShape.circle,
image: DecorationImage(
image: AssetImage(
"assets/images/IMG2.jpg"),
fit: BoxFit.cover,
),
),
),
Positioned(
bottom: 0,
right: 0,
child: Container(
height: 55,
width: 55,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
width: 5,
color: Theme.of(context)
.scaffoldBackgroundColor,
),
color: Cyan,
),
child: IconButton(
icon: Icon(
Icons.edit,
color: Dark_Blue,
),
onPressed:
() {}, // change profile picture
),
),
),
],
),
),
addVertical(30),
Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.only(
top: 25, left: 35, right: 35, bottom: 10),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
buildTextFormField(
"Full Name",
userData.fname ??
"Enter Full Name here...",
false,
false ?? null,
),
addVertical(15),
buildTextFormField(
"Contact",
userData.contact ?? "020 *** ****",
true,
false ?? null,
),
addVertical(15),
buildTextFormField(
"E-mail",
userData.email ?? "emaple123#gmail.com",
false,
true ?? null,
),
],
),
),
),
),
addVertical(35),
Padding(
padding: const EdgeInsets.only(
left: 35, right: 35, top: 25),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
primary: White,
),
onPressed: () {
Navigator.pop(context);
},
child: Text(
"CANCEL",
style: themeData.textTheme.bodyText1
.copyWith(
letterSpacing: 1.25,
fontWeight: FontWeight.bold,
fontSize: 18,
color: Mid_Blue,
),
),
),
ElevatedButton(
onPressed: () async {
if (_formKey.currentState.validate()) {
setState(() => loading = true);
dynamic result =
await _auth.currentUser;
// User person = result.user;
if (result != null) {
await Database(uid: doc.uid)
.updateData(
"$name",
"$email",
"$contact",
);
Toast.show(
"Your details have been successfully updated!",
context,
duration: Toast.LENGTH_LONG,
gravity: Toast.BOTTOM,
);
setState(() => loading = false);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
Homepage()));
} else {
Toast.show(
"Please try again later",
context,
gravity: Toast.BOTTOM,
duration: Toast.LENGTH_LONG,
);
}
}
},
style: ElevatedButton.styleFrom(
elevation: 2,
primary: Colors.green[300],
shape: new RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
), //!elevatedButton background
),
child: Text(
"SAVE",
style: TextStyle(
fontSize: 18,
letterSpacing: 2.2,
color: White,
),
),
),
],
),
),
],
//),
),
),
),
);
} else {
return Loading();
}
},
),
);
}
Widget buildTextFormField(
String labelText,
String placeholder,
bool isPhone,
bool isEmail,
) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 10),
child: TextField(
onSubmitted: isPhone || isEmail
? (value) {
value = _phoneController.toString() != null
? _emailController.toString() != null
: _nameController;
}
: null,
controller: isEmail || isPhone
? (value) {
value = _emailController.toString() != null
? _nameController.toString() != null
: _phoneController;
}
: _emailController,
obscureText: isPhone ? showPhone : false,
decoration: InputDecoration(
suffixIcon: isPhone
? IconButton(
onPressed: () => setState(() => showPhone = !showPhone),
icon: Icon(
Icons.remove_red_eye,
color: Red,
),
)
: null, //!This makes the icon appear only for the password field
contentPadding: EdgeInsets.only(bottom: 3),
labelText: labelText,
labelStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Aqua,
),
floatingLabelBehavior: FloatingLabelBehavior.always,
hintText: placeholder,
hintStyle: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Cyan,
),
),
keyboardType:
isPhone ? TextInputType.phone : TextInputType.emailAddress,
),
);
}
}
This is the function that builds name textField
buildTextFormField(
"Full Name",
userData.fname ?? "Enter Full Name here...",
false, // isPhone
false ?? null, // isEmail
),
From here we can see that isPhone = false; isEmail = false;
This is the function for the and controller in TextFormField:
controller: isEmail || isPhone
? (value) {
value = _emailController.toString() != null
? _nameController.toString() != null
: _phoneController;
}
: _emailController,
Since isEmail and isPhone are both false, it returns _emailController for name Textfield. So name is being updated on email textfield.
The function for onSubmitted() returns null if isEmail & isPhone are both false. Therefore, for name field, it will return null as the value (probably why you are getting null in the database).
I have tried to better organise the code below:
class MyHomePage extends StatefulWidget {
final String email;
MyHomePage({Key key, this.email}) : super(key: key);
get user => AuthService();
#override
_MyHomePageState createState() => _MyHomePageState(email);
}
class _MyHomePageState extends State<MyHomePage> {
String email;
// not used in this class
String contain;
_MyHomePageState(this.email);
bool showPhone = false;
//Text editing controller
final TextEditingController _emailController = TextEditingController();
final TextEditingController _phoneController = TextEditingController();
final TextEditingController _nameController = TextEditingController();
#override
void dispose() {
// Clean up the controller when the widget is removed from the
// widget tree.
_emailController.dispose();
_phoneController.dispose();
_nameController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
final FirebaseAuth _auth = FirebaseAuth.instance;
bool loading = false;
final _formKey = GlobalKey<FormState>();
final doc = Database();
final ThemeData themeData = Theme.of(context);
return loading
? Loading()
: SafeArea(
child: StreamBuilder<UserData>(
stream: Database(uid: doc.uid).userData,
builder: (context, snapshot) {
if (snapshot.hasData) {
UserData userData = snapshot.data;
_emailController.text = userData.email;
_phoneController.text = userData.phone;
_nameController.text = userData.name;
return Scaffold(
appBar: AppBar(
backgroundColor: Aqua,
elevation: 1,
title: Text(
'Edit Profile Info',
style: themeData.textTheme.headline1.copyWith(
color: White,
fontSize: 22,
letterSpacing: 0.75,
),
),
),
body: new Container(
height: window.physicalSize.height * 0.85,
padding: const EdgeInsets.only(
left: 16,
right: 16,
top: 25,
),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
new Center(
child: new Stack(
children: [
addVertical(20),
Container(
width: 190,
height: 190,
decoration: BoxDecoration(
border: Border.all(
width: 5,
color: Theme.of(context)
.scaffoldBackgroundColor,
),
boxShadow: [
BoxShadow(
blurRadius: 15,
spreadRadius: 5,
color: Cyan.withOpacity(0.5),
offset: Offset(0, 15),
),
],
shape: BoxShape.circle,
image: DecorationImage(
image: AssetImage(
"assets/images/IMG2.jpg"),
fit: BoxFit.cover,
),
),
),
Positioned(
bottom: 0,
right: 0,
child: Container(
height: 55,
width: 55,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
width: 5,
color: Theme.of(context)
.scaffoldBackgroundColor,
),
color: Cyan,
),
child: IconButton(
icon: Icon(
Icons.edit,
color: Dark_Blue,
),
onPressed:
() {}, // change profile picture
),
),
),
],
),
),
addVertical(30),
Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.only(
top: 25, left: 35, right: 35, bottom: 10),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
buildTextFormField(
"Full Name",
"Enter Full Name here...",
false,
_nameController,
),
addVertical(15),
buildTextFormField(
"Contact",
"020 *** ****",
true,
_phoneController,
),
addVertical(15),
buildTextFormField(
"E-mail",
"example123#gmail.com",
false,
_nameController,
),
],
),
),
),
),
addVertical(35),
Padding(
padding: const EdgeInsets.only(
left: 35, right: 35, top: 25),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
primary: White,
),
onPressed: () {
Navigator.pop(context);
},
child: Text(
"CANCEL",
style: themeData.textTheme.bodyText1
.copyWith(
letterSpacing: 1.25,
fontWeight: FontWeight.bold,
fontSize: 18,
color: Mid_Blue,
),
),
),
ElevatedButton(
onPressed: () async {
if (_formKey.currentState.validate()) {
setState(() => loading = true);
dynamic result =
await _auth.currentUser;
// User person = result.user;
if (result != null) {
await Database(uid: doc.uid)
.updateData(
_nameController.text,
_emailController.text,
_phoneController.text,
);
Toast.show(
"Your details have been successfully updated!",
context,
duration: Toast.LENGTH_LONG,
gravity: Toast.BOTTOM,
);
setState(() => loading = false);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
Homepage()));
} else {
Toast.show(
"Please try again later",
context,
gravity: Toast.BOTTOM,
duration: Toast.LENGTH_LONG,
);
}
}
},
style: ElevatedButton.styleFrom(
elevation: 2,
primary: Colors.green[300],
shape: new RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
), //!elevatedButton background
),
child: Text(
"SAVE",
style: TextStyle(
fontSize: 18,
letterSpacing: 2.2,
color: White,
),
),
),
],
),
),
],
//),
),
),
),
);
} else {
return Loading();
}
},
),
);
}
Widget buildTextFormField(
String labelText,
String placeholder,
bool isPhone,
TextEditingController controller,
) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 10),
child: TextField(
// onSubmitted: isPhone || isEmail
// ? (value) {
// value = _phoneController.toString() != null
// ? _emailController.toString() != null
// : _nameController;
// }
// : null,
controller: controller,
obscureText: isPhone ? showPhone : false,
decoration: InputDecoration(
suffixIcon: isPhone
? IconButton(
onPressed: () => setState(() => showPhone = !showPhone),
icon: Icon(
Icons.remove_red_eye,
color: Red,
),
)
: null, //!This makes the icon appear only for the password field
contentPadding: EdgeInsets.only(bottom: 3),
labelText: labelText,
labelStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Aqua,
),
floatingLabelBehavior: FloatingLabelBehavior.always,
hintText: placeholder,
hintStyle: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Cyan,
),
),
keyboardType:
isPhone ? TextInputType.phone : TextInputType.emailAddress,
),
);
}
}

Enabled button with. a state variable in a blocbuilder

I have a bloc which I use to upload images from the gallery. I then have a TextField where I enter text. And finally another bloc where I have a button. The button is used to submit the data to a server(image and text). My problem is enabling the button. My code for enabling is:
class ObservationPage extends StatefulWidget {
#override
_ObservationPageState createState() => _ObservationPageState();
}
class _ObservationPageState extends State<ObservationPage> {
List<File> files = [];
TextEditingController _descriptionController = TextEditingController();
TextEditingController _taskNameController = TextEditingController();
String taskName;
List<String> _selectedUsers = [];
bool _enabled = false;
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
BlocProvider.of<ImageBloc>(context).add(DeleteAllImages(files: files));
return true;
},
child: Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
centerTitle: true,
iconTheme: IconThemeData(
color: RioColours.darkGrey,
),
backgroundColor: Colors.grey[200],
elevation: 0,
title: Text('Observation',style:TextStyle(color: Colors.black))
),
body: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.only(left: 20.0, right: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 20,),
Column(children: [
AutoSizeText(
'Make an Observation and assign to a colleague ',
maxLines: 1,
style: RioTextStyle.auditQuestion(context),
),
SizedBox(height: 20,),
AttachPhoto(),
SizedBox(height: 20,),
BlocBuilder<ImageBloc, ImageState>(builder: (context, state) {
if (state is ImageInitial) {
return Container();
}
if (state is ImageLoadInProgress) {
return CircularProgressIndicator();
}
if (state is ImageLoadSuccess) {
//print(state.files);
files = state.files;
return SizedBox(
//height: MediaQuery.of(context).size.height*.5,
child: ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: state.files.length,
itemBuilder: (context, item) {
return Padding(
padding: const EdgeInsets.only(bottom:10.0),
child: ImageContainer(context: context, file: state.files[item]),
);
}),
);
}
if (state is NoImages) {
return Container();
}
if (state is ImageLoadFailure) {
return Container();
}
return Container();
})
]),
Text(
'Notes',
style: RioTextStyle.auditHeaders(context),
),
SizedBox(
height:10
),
SizedBox(height: 140,
child: TextField(
textInputAction: TextInputAction.next,
keyboardType: TextInputType.multiline,
maxLines: 5,
controller: _descriptionController,
onChanged: (String value) {
setState(() {});
},
style: TextStyle(fontSize: 16.0, height: 2.0, color: Colors.black),
decoration: new InputDecoration(
hintStyle: RioTextStyle.hintText(context),
fillColor: Colors.white,
filled: true,
focusedBorder: OutlineInputBorder(),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.grey[300]),
),
hintText: "Enter your notes here"
),
),
),
SizedBox(
height: MediaQuery.of(context).size.height * .04,
),
Text(
'Task Name',
style: RioTextStyle.auditHeaders(context),
),
SizedBox(
height: 10
),
TextField(
controller: _taskNameController,
onChanged: (String value) {
setState(() {});
},
textInputAction: TextInputAction.next,
style: TextStyle(fontSize: 16.0, height: 2.0, color: Colors.black),
decoration: new InputDecoration(
fillColor: Colors.white,
filled: true,
focusedBorder: OutlineInputBorder(),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.grey[300]),
),
hintStyle: RioTextStyle.hintText(context),
hintText: "Enter your task name here"
),
),
SizedBox(
height: 20
),
SizedBox(
height: 20
),
BlocBuilder<ObservationBloc, ObservationState>(builder: (context, state) {
if (state is UsersLoadInProgress) {
return Center(child: CircularProgressIndicator());
}
if (state is UsersLoadSuccess) {
final users = state.users;
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text(
'Assign to',
style: RioTextStyle.auditHeaders(context),
),
SizedBox(
height: MediaQuery.of(context).size.height * .02,
),
MultiSelectDialogField(
buttonIcon: Icon(Icons.arrow_drop_down,color: Colors.grey,),
chipDisplay: MultiSelectChipDisplay(
chipColor: Colors.white,
textStyle: TextStyle(color: Colors.black),
),
onConfirm: (results) {
_selectedUsers.clear();
for (User user in results) {
_selectedUsers.add(user.id);
setState(() {
_enabled = true;
});
}
// _selectedUsers = results;
print(_selectedUsers);
},
items: users.map((user) => MultiSelectItem<User>(user, user.first_name)).toList(),
title: Text(
'Assign Owners',
style: TextStyle(color: RioColours.splashBlue),
),
cancelText: Text(
"CANCEL",
style: TextStyle(color: RioColours.splashBlue),
),
confirmText: Text(
"ASSIGN",
style: TextStyle(color: RioColours.splashBlue),
),
buttonText: Text(
"Choose Owners",
style: RioTextStyle.dropDownHint(context),
),
),
SizedBox(
height: MediaQuery.of(context).size.height * .05,
),
]);
}
if (state is UserLoadFailure) {
return Text('error');
}
return Container();
}),
BlocConsumer<ButtonBloc, ButtonState>(listener: (context, state) {
if (state is UploadFailure) {
RioHelpers.showFailureFlushBar(context, 'Error Uploading');
Navigator.of(context).pop();
}
if (state is UpLoadSuccess) {
_submit();
}
}, builder: (context, state) {
if (state is Loading) {
return Center(child: CircularProgressIndicator());
}
if (state is ButtonInitial) {
print(_enabled);
return SizedBox(
height: MediaQuery.of(context).size.height * .07,
width: MediaQuery.of(context).size.width,
child: RaisedButton(
onPressed: (_descriptionController.text.isNotEmpty && _taskNameController.text.isNotEmpty && _enabled) ? () => callupLoad() : null,
color: RioColours.splashBlue,
child: Text(
'Submit',
style: RioTextStyle.buttonText(context),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
),
),
);
}
if (state is UpLoadSuccess) {
BlocProvider.of<ImageBloc>(context).add(DeleteAllImages(files: files));
return SizedBox(
height: MediaQuery.of(context).size.height * .07,
width: MediaQuery.of(context).size.width,
child: RaisedButton(
onPressed: (_descriptionController.text.isNotEmpty && _taskNameController.text.isNotEmpty && _enabled) ? () => callupLoad() : null,
color: RioColours.splashBlue,
child: Text(
'Submit',
style: RioTextStyle.buttonText(context),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
),
),
);
}
if (state is UploadFailure) {
return SizedBox(
height: MediaQuery.of(context).size.height * .07,
width: MediaQuery.of(context).size.width,
child: RaisedButton(
onPressed: () {},
//onPressed: (controller.text.isNotEmpty && _enabled) ? () => callupLoad() : null,
color: RioColours.splashBlue,
child: Text(
'Submit',
style: RioTextStyle.buttonText(context),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
),
),
);
}
return Container(
color: Colors.yellow,
height: 10,
);
}),
SizedBox(
height: MediaQuery.of(context).size.height * .12,
),
],
),
),
)),
);
}
callupLoad() {
BlocProvider.of<ButtonBloc>(context).add(UploadTaskRequest(files: files, notes: _descriptionController.text, taskName: _taskNameController.text, owners: _selectedUsers));
}
_submit() async {
print('called called called called called ');
RioHelpers.showSuccessFlushBar(context, 'Observation recorded');
BlocProvider.of<ImageBloc>(context).add(DeleteAllImages(files: files));
await Future.delayed(Duration(seconds: 3));
Navigator.of(context).pop();
}
#override
void initState() {
BlocProvider.of<ObservationBloc>(context).add(RequestUsers());
super.initState();
print("init calledx");
_enabled = false;
}
}
So the _controller works great for enabling/disabling the button. However _enabled which is a boolean state variable is my problem. In my blocbuilder I update my state to _enabled= true when the image upload is successful. However this is not making any difference to enabling the button. I've also updated the state variable using a bloclistener but that didn't work either.
How can I trigger the button to be enabled when I upload an image from the Gallery
Set a local variable in the builder, not in the class itself, unless you want to use in another place. If you want to do so, wrap the variable assignment in a setState call.

How to add item in a listview from one class to another in Flutter?

I am working on a project in which i have a class which has a row that has two children. Child one contains a TabView with a child class TabViewChild in which i am generating a gridview. On the other hand child two contains a listView. So the problem is, when i click on the gridview item i am passing that item's value to a static list and passing that list to a listview of other class. But i have no idea how to change the state of that class on item clicked or how can i achieve this task in a better way as i am new to Flutter. I want that when a person click on any gridview's item that item appears in the listview simultaneously.
class ItemMenus {
int id;
String code;
String name;
String salePrice;
String photo;
String categoryName;
String percentage;
int quantity;
ItemMenus({this.id, this.code, this.name, this.salePrice, this.photo,
this.categoryName, this.percentage, this.quantity});
ItemMenus.fromJson(Map<String, dynamic> json)
:
id = int.parse(json['id']),
code = json['code'],
name = json['name'],
salePrice = json['sale_price'],
photo = json['photo'],
categoryName = json['category_name'],
percentage = json['percentage'];
#override
String toString() {
return 'ItemMenus{id: $id, code: $code, name: $name, salePrice: $salePrice, photo: $photo, categoryName: $categoryName, percentage: $percentage}';
}
}
import 'package:food_app/model/mdl_item_menus.dart';
class ItemMenuList{
List<ItemMenus> _itmMenuLst = [];
ItemMenuList._();
static final ItemMenuList instanceItmMenuLst = ItemMenuList._();
static ItemMenuList get instance => instanceItmMenuLst;
void addItem(ItemMenus im){
_itmMenuLst.add(im);
}
List<ItemMenus> get list => _itmMenuLst;
#override
String toString() {
return 'ItemMenuList{_itmMenuLst: $_itmMenuLst}';
}
}
import 'package:flutter/material.dart';
import 'package:food_app/database/tables/tbl_categories.dart';
import 'package:food_app/model/list/item_menu_list.dart';
import 'package:food_app/model/mdl_categories.dart';
import 'package:food_app/model/mdl_item_menus.dart';
import 'package:food_app/pos/tab_bar_view.dart';
class EPos extends StatefulWidget{
#override
_EPosState createState() => _EPosState();
}
class _EPosState extends State<EPos> {
final categoryDBHelper = TblCategories.categoriesInstance;
final ItemMenuList instance2 = ItemMenuList.instance;
String _orderType = 'Dine-In', _info = 'Table No. 1', _userName = 'ZiaUddin';
List<Categories> catLst = [];
List<ItemMenus> itmLst = [];
Future getCategories() async {
catLst.clear();
var categories = await categoryDBHelper.getCategories();
categories.forEach((element) {
catLst.add(Categories(
id: element['id'],
categoryName: element['category_name'],
description: element['description'],
userId: element['user_id'],
companyId: element['company_id'],
delStatus: element['del_status']));
});
catLst.forEach((element) {
print(element);
});
return catLst;
}
#override
void initState() {
// TODO: implement initState
super.initState();
// itmLst = instance2.list;
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Column(
children: [
//#region AppBar
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.15,
color: Colors.redAccent,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
margin: EdgeInsets.fromLTRB(8, 10, 0, 0),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(20),
color: Colors.red,
),
child: Row(
children: [
Icon(
Icons.arrow_back,
color: Colors.white,
size: 25,
),
Padding(
padding: const EdgeInsets.fromLTRB(4, 8, 10, 8),
child: Text(
_orderType,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
fontFamily: 'Ubuntu',
letterSpacing: 2.0,
),
),
),
],
),
),
Container(
margin: EdgeInsets.fromLTRB(8, 10, 0, 0),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10),
color: Colors.red,
),
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 8, 20, 8),
child: Text(
_info,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.amberAccent,
fontFamily: 'Ubuntu',
letterSpacing: 2.0,
),
),
),
),
Container(
margin: EdgeInsets.only(top: 15, right: 5),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(30),
color: Colors.red,
),
child: Row(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(10, 8, 8, 8),
child: Text(
_userName,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.normal,
color: Colors.white,
fontFamily: 'Ubuntu',
letterSpacing: 1.0,
),
),
),
CircleAvatar(
backgroundColor: Colors.red,
radius: MediaQuery.of(context).size.height * 0.041,
child: CircleAvatar(
radius: MediaQuery.of(context).size.height * 0.04,
backgroundImage: AssetImage('assets/user.png'),
),
),
],
),
),
],
),
),
//endregion
Expanded(
child: Row(
children: [
//# region Menu
Flexible(
flex: 1,
child: Container(
decoration: BoxDecoration(
color: Colors.yellowAccent,
shape: BoxShape.rectangle,
),
child: Column(
children: [
Expanded(
child: Container(
color: Colors.white,
child: FutureBuilder(
future: getCategories(),
builder: (context, snapShot) {
if (snapShot.connectionState ==
ConnectionState.none &&
snapShot.hasData == null) {
return Center(
child: CircularProgressIndicator());
}
return MaterialApp(
debugShowCheckedModeBanner: false,
home: DefaultTabController(
length: catLst.length,
child: Scaffold(
backgroundColor: Colors.white,
appBar: PreferredSize(
preferredSize:
Size.fromHeight(kToolbarHeight),
child: Container(
height: MediaQuery.of(context)
.size
.height *
0.1,
child: TabBar(
indicatorColor:
Colors.amberAccent,
isScrollable: true,
tabs: catLst
.map<Widget>((Categories c) {
return Tab(
icon: Icon(
Icons.style,
color: Colors.amberAccent,
size: 15,
),
child: Text(
c.categoryName
.toUpperCase(),
style: TextStyle(
color: Colors.black,
fontWeight:
FontWeight.w400,
),
),
);
}).toList(),
),
),
),
body: TabBarView(
children: catLst.map((Categories c) {
return TabBarViewChild(categoryName:c.categoryName,
callback: (){
setState(() {
instance2.addItem(ItemMenus(name: c.categoryName));
itmLst = instance2.list;
print('I am Callback');
});
},);
}).toList(),
),
),
),
);
}),
),
),
],
),
),
),
//endregion
//# region OrderList
Flexible(
flex: 1,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
),
child: ListView.builder(
itemCount: itmLst.length,
itemBuilder: (context, index){
return ListTile(
title: Text(itmLst[index].name),
);
},
),
),
),
//endregion
],
),
),
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:food_app/database/tables/tbl_item_menus.dart';
import 'package:food_app/model/list/item_menu_list.dart';
import 'package:food_app/model/mdl_item_menus.dart';
import 'package:food_app/pos/new_sale.dart';
class TabBarViewChild extends StatefulWidget {
String categoryName;
VoidCallback callback;
TabBarViewChild({Key key,#required this.categoryName, this.callback}) : super(key:key);
#override
_TabBarViewChildState createState() => _TabBarViewChildState();
}
class _TabBarViewChildState extends State<TabBarViewChild> {
final ItemMenuList instance1 = ItemMenuList.instance;
List<ItemMenus> itmLst = [];
final itemMenus = TblItemMenus.itemMenusInstance;
Future getSpecificItemMenus() async{
var items = await itemMenus.getSpecificItemMenus(widget.categoryName);
itmLst.clear();
items.forEach((e) {
itmLst.add(ItemMenus(id: e['id'], categoryName: e['category_name'], code: e['code'],
name: e['name'], percentage: e['percentage'], photo: e['photo'], quantity: e['quantity'],
salePrice: e['sale_price']));
});
for (var value in itmLst) {
print(value);
}
return itmLst;
}
#override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
color: Colors.white,
child: FutureBuilder(
future: getSpecificItemMenus(),
builder: (context, snapShot) {
if (snapShot.connectionState == ConnectionState.none
&& snapShot.hasData == null) {
return Center(child: CircularProgressIndicator());
}
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
scrollDirection: Axis.vertical,
itemCount: itmLst.length,
itemBuilder: (context, index){
return Padding(
padding: const EdgeInsets.all(5.0),
child: InkWell(
child: Card(
elevation: 4,
color: Colors.amberAccent,
child: Center(
child: Text(
itmLst[index].name.toUpperCase(),
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.red,
fontSize: 13,
fontWeight: FontWeight.w700,
fontFamily: 'Ubuntu',
letterSpacing: 1.0,
),
),
),
),
onTap: (){
// Provider.of<ProItemMenus>(context, listen: false).addNewItemInList(ItemMenus(name: itmLst[index].name.toUpperCase()));
instance1.addItem(ItemMenus(categoryName: itmLst[index].name.toUpperCase()));
print(itmLst[index].name.toUpperCase());
},
),
);
}
);
}
),
);
}
}
So the problem now, there are two stateful widgets.
And as we are going to share the data or the state between them, basically we need to have more one stateful Widget which will the parent of them.
This term of is this problem known as State Management.
Currently there are many reknown State Management , such as Provider and Bloc. Reference.
But personally, I recommend to use Provider, which has simple Syntaxes and Concept.