How to fix when BackdropScaffold frontLayer's elements doesn't appear? - flutter

Sorry for the bad title:(!
My app should show in the home screen cards and FloatingActionButton, I've created the cards in separate file, so I'm forwarding the data to it, also to store my data I'm using sqlite which I'm new to it..
the FloatingActionButton should appear when I run the application, and I need it to add new cards. I know that the database is empty now, but why the FloatingActionButton is not appearing?
when running it it looks like this.
I had followed a tutorial in the part when using the sqlite, and this is a part of my homeScreen code :
frontLayer: FutureBuilder<List<Reminder>>(
future: _reminders,
builder: (context, snapshot) {
if (snapshot.hasData) {
_currentReminders = snapshot.data!;
return ListView(children: [
...snapshot.data!.map<Widget>((reminder) {
return ReminderCard(
name: reminder.name, details: reminder.details);
}).followedBy([
Scaffold(
backgroundColor: Colors.amber,
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.black,
child: Icon(Icons.add),
onPressed: () {},
),
)
]).toList(),
Padding(
padding: const EdgeInsets.all(8.0),
),
Scaffold(
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.black,
child: Icon(Icons.add),
onPressed: () {}
this is the full code if I didn't paste the right part of my code: https://github.com/RarLasebai/reminder3/blob/main/lib/ui/Screens/homeScreen.dart

i have cloned your project and did a little changes on the HomeScreen
here is how u should do it
import 'package:flutter/material.dart';
import 'package:backdrop/backdrop.dart';
import 'package:untitled/helper.dart';
import 'package:untitled/models/reminder.dart';
import 'package:untitled/ui/widgets/ReminderCard.dart';
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
TextEditingController nameController = TextEditingController();
TextEditingController detailsController = TextEditingController();
final _formKey = GlobalKey<FormState>();
late ReminderCard card;
RHelper helper = RHelper();
late Future<List<Reminder>> _reminders;
late List<Reminder> _currentReminders;
//-------------------------Functions----------------
bool status = true;
#override
void initState() {
super.initState();
helper.initializeDatabase().then((value) => {print("------------donne?")});
_loadReminders();
}
void _loadReminders() {
_reminders = helper.getReminders();
if (mounted) setState(() {});
}
//Screen and appBar frontend
#override
Widget build(BuildContext context) {
return BackdropScaffold(
backgroundColor: Colors.white,
appBar: BackdropAppBar(
centerTitle: true,
title: (Text(
'قائمة التذكيرات',
style: Theme.of(context).textTheme.headline1,
)),
),
headerHeight: 110.0,
frontLayer: FutureBuilder<List<Reminder>>(
future: _reminders,
builder: (context, snapshot) {
if (snapshot.hasData) {
_currentReminders = snapshot.data!;
return ListView(children: [
Column(
children: _currentReminders.map<Widget>((reminder) {
return ReminderCard(
name: reminder.name, details: reminder.details);
}).toList(),
),
Padding(
padding: const EdgeInsets.all(8.0),
),
]);
}
return Center(child: Text("Loading>>.."));
},
),
backLayer: BackdropNavigationBackLayer(
items: [
ListTile(
leading: ImageIcon(AssetImage('icons/to-do-list.png')),
title: Align(
alignment: Alignment.centerRight,
child: Text("التذكيرات",
style: Theme.of(context).textTheme.bodyText2)),
onTap: () {
Navigator.of(context).pushReplacementNamed('home');
}),
Divider(),
ListTile(
leading: ImageIcon(AssetImage('icons/athkar.png')),
title: Align(
alignment: Alignment.centerRight,
child: Text("الأذكار",
style: Theme.of(context).textTheme.bodyText2)),
onTap: () {
Navigator.of(context).pushReplacementNamed('athkar');
}),
Divider(),
ListTile(
leading: ImageIcon(AssetImage('icons/mosque.png')),
title: Align(
alignment: Alignment.centerRight,
child: Text("مواقيت الصلاة",
style: Theme.of(context).textTheme.bodyText2)),
onTap: () {
Navigator.of(context).pushReplacementNamed('adhan');
},
),
Divider(),
ListTile(
leading: ImageIcon(AssetImage('icons/Tasbeeh.png')),
title: Align(
alignment: Alignment.centerRight,
child: Text("تسبيح",
style: Theme.of(context).textTheme.bodyText2)),
onTap: () {
Navigator.of(context).pushReplacementNamed('tasbeeh');
},
),
Divider(),
ListTile(
leading: ImageIcon(AssetImage('icons/quran.png')),
title: Align(
alignment: Alignment.centerRight,
child: Text("مصحف",
style: Theme.of(context).textTheme.bodyText2)),
onTap: () {
Navigator.of(context).pushReplacementNamed('moshaf');
},
),
Divider(),
ListTile(
leading: ImageIcon(AssetImage('icons/tadabur.png')),
title: Align(
alignment: Alignment.centerRight,
child: Text("وقفات تدبرية ",
style: Theme.of(context).textTheme.bodyText2)),
onTap: () {
Navigator.of(context).pushReplacementNamed('tadabur');
}),
Divider(),
ListTile(
leading: ImageIcon(AssetImage('icons/information.png')),
title: Align(
alignment: Alignment.centerRight,
child: Text("تواصل معنا",
style: Theme.of(context).textTheme.bodyText2)),
onTap: () {
Navigator.of(context).pushReplacementNamed('contact');
})
],
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
showModalBottomSheet(
useRootNavigator: true,
context: context,
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(24),
),
),
builder: (context) {
return StatefulBuilder(
builder: (context, setModalState) {
return Container(
padding: const EdgeInsets.all(32),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
validator: (String? value) {
if (value!.isEmpty)
return 'Please enter name';
},
controller: detailsController,
style: TextStyle(
color: Colors.black, fontSize: 15.0),
decoration: InputDecoration(
errorStyle: TextStyle(
color: Colors.red, fontSize: 15.0),
labelText: 'اسم التذكير',
labelStyle: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 15.0,
),
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(5.0)),
),
),
SizedBox(
height: 10,
),
TextFormField(
controller: nameController,
style: TextStyle(
color: Colors.black, fontSize: 15.0),
decoration: InputDecoration(
labelText: 'التفاصيل',
labelStyle: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 15.0,
),
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(5.0)),
),
),
SizedBox(
height: 10,
),
ElevatedButton(
onPressed: () {
setState(() {
if (_formKey.currentState!
.validate()) {
_save();
Navigator.pop(context);
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(
content: Text(
'تم حفظ التذكير')));
}
});
},
child: Text('حفظ'),
)
],
),
),
);
});
},
);
})
);
}
void _save() {
var _reminder = Reminder(
name: nameController.text, details: detailsController.text, save: 0);
helper.insertReminder(_reminder);
_loadReminders();
}
}
and for a athkar project i really suggest that you use provider or riverpod , or any kind of state management

Related

Why does ontap change all cards

I am still new to coding and still learning dart. I can't find a solution anywhere. please help. when I run my code, everything works fine but when i add multiple cards, when i tap one, they all change color and have a strikethrough. I am not sure where the problem is. Please can you help, here is my code:
#override
bool _enabled = true;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('To-Do List'),
centerTitle: true,
backgroundColor: Colors.grey[900],
),
body: ListView(children: _getItems()),
backgroundColor: Colors.grey[850],
floatingActionButton: Padding(
padding: const EdgeInsets.all(8.0),
child: FloatingActionButton(
onPressed: () => _displayDialog(context),
tooltip: 'Add Item',
child: Icon(Icons.add),
backgroundColor: Colors.grey[900],
),
),
);
}
void _addTodoItem(String title) {
//Wrapping it inside a set state will notify
// the app that the state has changed
setState(() {
_todoList.add(title);
});
_textFieldController.clear();
}
final Map<String, bool> _enabledMap = Map<String, bool>();
Widget _buildTodoItem(String title) {
return Padding(
padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 0.0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: InkWell(
onTap: () => setState(() {
item.isTapped = !item.isTapped;
// _enabled = !_enabled;
// _color = Colors.grey;
}),
child: Container(
child: Container(
width: 50,
height: 75,
alignment: Alignment.center,
child: Text(
title,
style: TextStyle(decoration: _enabledMap[title] == true ? TextDecoration.lineThrough, color : null: Colors.grey[700]),
),
color: _color,
),
),
)
);
}
//Generate a single item widget
_displayDialog(BuildContext context) async {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Add a task to your List'),
content: TextField(
controller: _textFieldController,
decoration: const InputDecoration(hintText: 'Enter task here'),
),
actions: <Widget>[
FlatButton(
child: const Text('CANCEL'),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(
child: const Text('ADD'),
onPressed: () {
Navigator.of(context).pop();
_addTodoItem(_textFieldController.text);
},
),
],
);
});
}
Your onTap method updates the _enabled variable in setState.
That variable is used for all the containers in their TextStyle widget.
In order to select one item, I suggest creating a map that'll store your "enabled" logic, and the key should be a unique String (the title).
Something like below: (not tested)
final Map<String, bool> _enabledMap = Map<String, bool>();
enter code here
Widget _buildTodoItem(String title) {
return Padding(
padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 0.0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: InkWell(
onTap: () => setState(() { if (_enabledMap[title] == null) {_enabledMap[title] = false;} _enabledMap[title] = !_enabledMap[title]; _color = Colors.grey;}),
child: Container(
width: 50,
height: 75,
alignment: Alignment.center,
child: Text(
title,
style: TextStyle(decoration: _enabledMap[title] == true ? TextDecoration.lineThrough, color: Colors.grey[700] : null),
),
color: _color,
),
),
)
);
class Details {
String title;
bool isTapped;
Details({this.title, this.isTapped});
}
class Testing2 extends StatefulWidget {
#override
_Testing2State createState() => _Testing2State();
}
class _Testing2State extends State<Testing2> {
#override
bool _enabled = true;
List<Details> _todoList = [];
List<Widget> lists = [];
TextEditingController _textFieldController = TextEditingController();
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('To-Do List'),
centerTitle: true,
backgroundColor: Colors.grey[900],
),
body: _getItems(), //ListView(children: _getItems()),
backgroundColor: Colors.grey[850],
floatingActionButton: Padding(
padding: const EdgeInsets.all(8.0),
child: FloatingActionButton(
onPressed: () => _displayDialog(context),
tooltip: 'Add Item',
child: Icon(Icons.add),
backgroundColor: Colors.grey[900],
),
),
);
}
Widget _getItems() {
return Container(
child:_todoList.length>0? ListView.builder(
itemCount: _todoList.length,
itemBuilder: (context, index) {
return _buildTodoItem(_todoList[index]);
})
:Center(child: Text("It's Empty", style: TextStyle(color: Colors.white),),),
);
}
void _addTodoItem(String title) {
setState(() {
_todoList.add(Details(isTapped: false, title: title));
});
_textFieldController.clear();
}
Widget _buildTodoItem(Details item) {
return Padding(
padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 0.0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: InkWell(
onTap: () => setState(() {
item.isTapped = !item.isTapped;
}),
child: Container(
width: 50,
height: 75,
alignment: Alignment.center,
child: Text(
item.title,
style: TextStyle(
decoration:
item.isTapped ? null : TextDecoration.lineThrough,
color: Colors.grey[700]),
),
color: item.isTapped ? Colors.grey : null,
// _color
),
)));
}
//Generate a single item widget
_displayDialog(BuildContext context) async {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Add a task to your List'),
content: TextField(
controller: _textFieldController,
decoration: const InputDecoration(hintText: 'Enter task here'),
),
actions: <Widget>[
FlatButton(
child: const Text('CANCEL'),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(
child: const Text('ADD'),
onPressed: () {
Navigator.of(context).pop();
_addTodoItem(_textFieldController.text);
},
),
],
);
});
}
}

Navigator.pop shows me a black screen

It's been a while since I've been blocking backtracking on my flutter application, I tried the Navigator.pop (context) but I still ran into a black screen, I searched the forums for success but I'm still stuck. I want that when I click on return that it brings me back to my previous page without initializing the page
import 'package:MerchantIsland/log/database.dart';
import 'package:MerchantIsland/pages/home.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class productPage extends StatefulWidget {
final String productId;
const productPage({Key key, this.productId}) : super(key: key);
#override
_productPageState createState() => _productPageState();}
class _productPageState extends State<productPage> {
#override
Widget build(BuildContext context) {
ProductService productService = ProductService();
return WillPopScope(
onWillPop: (){
MovetoPreviousScreen();},
child: Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: (){
MovetoPreviousScreen();
},
),
centerTitle: true,
title: Text(
'Merchant island',
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
),
body: Stack(
children: [
FutureBuilder(
future: productService.ProductData.doc(widget.productId).get(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Scaffold(
body: Center(
child: Text("Error: ${snapshot.error}"),
),
);
}
if(snapshot.connectionState==ConnectionState.done){
Map<String, dynamic> documentData=snapshot.data.data();
return ListView(
children: [
Container(
height: 400.0,
child: Image.network(
"${documentData['pictures'][0]}",
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0,horizontal: 24.0),
child: Text('${documentData['productName']}'??"Nom du produit",
style:TextStyle(
fontSize: 28.0,
fontWeight: FontWeight.bold,
) ,),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0,horizontal: 24.0),
child: Text('${documentData['price']}',
style:TextStyle(
fontSize: 22.0,
fontWeight: FontWeight.bold,
color:Colors.red
) ),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0,horizontal: 24.0),
child: Text('${documentData['description']}',
style:TextStyle(
fontSize: 18
) ),
)
],
);
}
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}),
],
),
),
); }
// ignore: non_constant_identifier_names
void MovetoPreviousScreen() {
Navigator.of(context).pop(); }}
return page
import 'package:MerchantIsland/log/database.dart';
import 'package:MerchantIsland/log/loginUI.dart';
import 'package:MerchantIsland/pages/Sellproduct.dart';
import 'package:MerchantIsland/pages/bidPage.dart';
import 'package:MerchantIsland/products/productPage.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:MerchantIsland/pages/profil.dart';
import 'package:MerchantIsland/pages/balance.dart';
import 'package:MerchantIsland/pages/Settings.dart';
import 'package:google_sign_in/google_sign_in.dart';
// ignore: camel_case_types
class home extends StatefulWidget {
#override
_homeState createState() => _homeState();}
// ignore: camel_case_types
class _homeState extends State<home> {
ProductService productService = ProductService();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: false,
title: Text("Merchant Island"),
actions: [
IconButton(
icon: Icon(Icons.search, color: Colors.white,), onPressed: null,),
],
),
body: Stack(
children: [
FutureBuilder<QuerySnapshot>(
future: productService.ProductData.get(),
builder:(context,snapshot){
if(snapshot.hasError){
return Scaffold(
body: Center(
child: Text("Error: ${snapshot.error}"),
),
);
}
if(snapshot.connectionState==ConnectionState.done){
return Container(
child: ListView(
children: snapshot.data.docs.map((documents){
return Container(
child: GestureDetector(
onTap: (){
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context)=>productPage(productId: documents.id,)));
},
child: Container(
child: productCard(documents.data()["productName"],documents.data()["category"], documents.data()["price"],documents.data()["pictures"]) ,
),
),
);
}).toList(),
),
);
}
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}),
],
),
drawer: BDrawer(context),
); }}
// ignore: non_constant_identifier_names
Drawer BDrawer(BuildContext context) {
FirebaseAuth _auth = FirebaseAuth.instance;
GoogleSignIn _googleSignIn = GoogleSignIn();
Future <void> signOut() async {
await _auth.signOut();
await _googleSignIn.disconnect();
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => LoginUI()));}
return Drawer(
child: ListView(
children: [
UserAccountsDrawerHeader(
accountName: Text('TITAN', style: TextStyle(
fontSize: 18.0,
),),
accountEmail: Text('philippetankoano#gmail.com'),
currentAccountPicture: GestureDetector(
child: CircleAvatar(
backgroundColor: Colors.grey,
child: Icon(
Icons.person, color: Colors.white
),
),
),
otherAccountsPictures: [
InkWell(
onTap: () =>
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => profil(),)),
child: (
Icon(
Icons.mode_edit, size: 30.0,
)
),
)
],
),
InkWell(
onTap: () =>
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => balancepage())),
child: ListTile(
leading: Icon(
Icons.account_balance, size: 30.0, color: Colors.blue,),
title: Text(' Balance', style: TextStyle(
fontSize: 18.0,
),),
),
),
InkWell(
onTap: () =>
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => home())),
child: ListTile(
leading: Icon(Icons.home, size: 30.0, color: Colors.blue,),
title: Text(' Home', style: TextStyle(
fontSize: 18.0,
),),
),
),
InkWell(
onTap: () =>
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => SellProduct())),
child: ListTile(
leading: Icon(
Icons.account_balance, size: 30.0, color: Colors.blue,),
title: Text(' Sell product', style: TextStyle(
fontSize: 18.0,
),),
),
),
InkWell(
onTap: () {},
child: ListTile(
leading: Icon(
Icons.shopping_basket_outlined, size: 40.0,
color: Colors.blue,),
title: Text('Sale', style: TextStyle(
fontSize: 18.0,
),),
),
),
InkWell(
onTap: () {},
child: ListTile(
leading: Icon(Icons.category, size: 30.0, color: Colors.blue,),
title: Text(' Categories', style: TextStyle(
fontSize: 18.0,
),),
),
),
InkWell(
onTap: () =>
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => bidPage())),
child: ListTile(
leading: Icon(
Icons.event_available, size: 40.0, color: Colors.blue,),
title: Text(' Bid', style: TextStyle(
fontSize: 18.0,
),),
),
),
Divider(),
InkWell(
onTap: () =>
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => Settingpage(),)),
child: ListTile(
leading: Icon(Icons.settings, size: 30.0, color: Colors.blue,),
title: Text(' Setting', style: TextStyle(
fontSize: 18.0,
),),
),
),
InkWell(
onTap: () {},
child: ListTile(
leading: Icon(Icons.help, size: 30.0, color: Colors.blue,),
title: Text(' Help', style: TextStyle(
fontSize: 18.0,
),),
),
),
InkWell(
onTap: () async {
signOut();
},
child: ListTile(
leading: Icon(Icons.exit_to_app, size: 30.0, color: Colors.blue,),
title: Text(' Deconnexion', style: TextStyle(
fontSize: 18.0,
),),
),
),
]
), );}
Padding productCard(String name,String category,String price,List imageUrl){
return Padding(
padding: const EdgeInsets.all(6.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10.0),
boxShadow: [
BoxShadow(
color: Colors.grey,
offset: Offset(-2,-1),
blurRadius: 5
)
] ),
child: GestureDetector(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(7.0),
child: Image.network(
"${imageUrl[0]}",
height: 500,
width: 450,
),
),
],
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(' $name ',style: TextStyle(fontSize: 24.0,fontWeight: FontWeight.bold)),
Text('$price ',style: TextStyle(fontSize: 20.0,fontWeight: FontWeight.bold,color: Colors.red)),
],
),
),
Text('Categorie: $category \n',style: TextStyle(fontSize: 24.0,)),
],
),
), ),);}
Method One(Recommended)
First check if there is more than one Material App in your project if found then remove all except the root one (Child of MyApp) if that does not work or you have only one MaterialApp in your project then only try second method
Method Two(Try only if method one doesn't solved your issue or you don't have more than one MaterialApp in your project)
Replace Navigator.of(context).pop(); with Navigator.of(context,rootNavigator:true).pop(context)
If you got a black screen, it's probably because you are popping the only screen in your stack.
If you want that Navigator.of(context).pop() remove only the last screen, you have to display the current screen with a Navigator.of(context).push()
When clicking on the custom back icon Leading with in flutter
Replace Navigator.of(context).pop(); with Navigator.of(context,rootNavigator:true).pop(context)
appBar: AppBar(
automaticallyImplyLeading: true,
backgroundColor: ColorConstants.kBlackColor,
leading: BackButton(
color: ColorConstants.kWhiteColor,
onPressed: (){
Navigator.of(context,rootNavigator:true).pop(context);
},
),
),
In my case the problem was having some Navigator.pop(context) inside other callback functions.
When I clicked the back button, a socket would close, and consequently call the callback function (that also called pop()), so I would have Navigator.pop(context) called more than one time. And since my Page widget was the second element of the stack, calling it 2 times would pop also the root, therefore generating the black screen.
What I did to fix it, even though I think there might be better solutions, was substituting all the Navigator.pop(context) calls with the following:
if (Navigator.canPop(context)) {
Navigator.pop(context);
}
Another possible solution would be to initialize a bool variable (or a some kind of counter) and then call pop() only if that variable is true, then set it to false.:
// init
bool variable = true;
if (variable) {
Navigator.pop(context);
variable = false;
}

Flutter General dialog box - set state not working

I have an issue with my General Dialog Box. I would like to display a star. Then I would like to change it state when the star is taped and replace the icon by a yellow Star.
But is does not work. The Dialog Box is not refreshed so the icon is not changing. Please, can you look at the source code below and point me into the right direction please?
Many thanks.
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:date_time_picker/date_time_picker.dart';
import 'package:gtd_official_sharped_focused/snackbar.dart';
String _isImportantInboxTask ;
String _isUrgentInboxTask ;
String inboxTaskDisplayed;
String isImportant = "false" ;
String isUrgent = "false" ;
String myProjectName ;
var taskSelectedID;
//---------------
//String _initialValue;
//_-----------------
var documentID;
var textController = TextEditingController();
var popUpTextController = TextEditingController();
class Inbox extends StatefulWidget {
Inbox({Key key}) : super(key: key);
#override
_InboxState createState() => _InboxState();
}
class _InboxState extends State<Inbox> {
GlobalKey<FormState> _captureFormKey = GlobalKey<FormState>();
bool isOn = true;
#override
Widget build(BuildContext context) {
void showAddNote() {
TextEditingController _noteField = new TextEditingController();
showDialog(
context: context,
builder: (BuildContext context) {
return CustomAlertDialog(
content: Container(
width: MediaQuery.of(context).size.width / 1.3,
height: MediaQuery.of(context).size.height / 4,
child: Column(
children: [
TextField(
controller: _noteField,
maxLines: 4,
decoration: InputDecoration(
border: const OutlineInputBorder(
borderSide:
const BorderSide(color: Colors.black, width: 1.0),
),
),
),
SizedBox(height: 10),
Material(
elevation: 5.0,
borderRadius: BorderRadius.circular(25.0),
color: Colors.white,
child: MaterialButton(
minWidth: MediaQuery.of(context).size.width / 1.5,
onPressed: () {
Navigator.of(context).pop();
CollectionReference users = FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.uid)
.collection('allTasks');
users
.add({'task_Name': _noteField.text,'task_Status': 'Inbox' })
.then((value) => print("User Document Added"))
.catchError((error) =>
print("Failed to add user: $error"));
},
padding: EdgeInsets.fromLTRB(10.0, 15.0, 10.0, 15.0),
child: Text(
'Add Note',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20.0,
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
),
);
});
}
return Scaffold(
appBar: new AppBar(
title: new Text('Inbox Page'),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.add_circle_outline,
color: Colors.white,
),
onPressed: () {
showAddNote();
// do something
},
),
],
),
drawer: MyMenu(),
backgroundColor: Colors.white,
body: Column(
//mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: MediaQuery.of(context).size.height / 1.4,
width: MediaQuery.of(context).size.width,
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.uid)
.collection('allTasks')
.where('task_Status', isEqualTo: 'Inbox')
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
return ListView(
children: snapshot.data.docs.map((document) {
return Wrap(
children: [Card(
child: SwipeActionCell(
key: ObjectKey(document.data()['task_Name']),
actions: <SwipeAction>[
SwipeAction(
title: "delete",
onTap: (CompletionHandler handler) {
CollectionReference users = FirebaseFirestore
.instance
.collection('Users')
.doc(
FirebaseAuth.instance.currentUser.uid)
.collection('allTasks');
users
.doc(document.id)
.delete()
.then((value) => print("Note Deleted"))
.catchError((error) => print(
"Failed to delete Task: $error"));
},
color: Colors.red),
],
child: Padding(
padding: const EdgeInsets.all(0.0),
child: ListTile(
leading: ConstrainedBox(
constraints: BoxConstraints(
minWidth: leadingIconMinSize,
minHeight: leadingIconMinSize,
maxWidth: leadingIconMaxSize,
maxHeight: leadingIconMaxSize,
),
child: Image.asset('assets/icons/inbox.png'),
),
title: GestureDetector(
child: Text(
//'task_Name' correspond au nom du champ dans la table
document.data()['task_Name'],
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
// Pour editer task
onDoubleTap: (){
taskSelectedID = FirebaseFirestore
.instance
.collection('Users')
.doc(
FirebaseAuth.instance.currentUser.uid)
.collection('allTasks')
.doc(document.id);
//Dialog
return showGeneralDialog(
context: context,
barrierDismissible: true,
barrierLabel: MaterialLocalizations.of(context)
.modalBarrierDismissLabel,
barrierColor: Colors.black45,
transitionDuration: const Duration(milliseconds: 20),
pageBuilder: (BuildContext buildContext,
Animation animation,
Animation secondaryAnimation) {
return Scaffold(
appBar: AppBar(
title: Text ('Edit Task'),
leading: InkWell(
child: Icon(Icons.close),
onTap:(){Navigator.of(context).pop();}
),
actions: [Padding(
padding: const EdgeInsets.fromLTRB(0, 0,16.0,0),
child: InkWell(
child: Icon(Icons.save),
onTap: () {
final loFormInbox = _captureFormKey
.currentState;
if (loFormInbox.validate()) {
loFormInbox.save();
CollectionReference users = FirebaseFirestore
.instance
.collection(
'Users')
.doc(FirebaseAuth
.instance
.currentUser.uid)
.collection(
'allTasks');
users
.add({
'task_Name': _valueTaskNameSaved,
})
.then((value) =>
print(
"Task Created"))
.catchError((
error) =>
print(
"Failed to add task: $error"));
showSimpleFlushbar(
context,
'Task Saved',
_valueTaskNameSaved,
Icons
.mode_comment);
loFormInbox.reset();
isImportant = 'false';
isUrgent = 'false';
}
}
),
)],
),
body: Center(
child: Container(
width: MediaQuery.of(context).size.width - 10,
height: MediaQuery.of(context).size.height - 80,
padding: EdgeInsets.all(20),
color: Colors.white,
child: Column(
children: [
Theme(
data: ThemeData(
inputDecorationTheme: InputDecorationTheme(
border: InputBorder.none,
)
),
child: Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0.0, 15.0, 1.0),
child: TextFormField(
initialValue: document.data()['task_Name'],
decoration: InputDecoration(hintText: "Task Name"),
maxLength: 70,
maxLines: 2,
onChanged: (valProjectName) => setState(() => _valueTaskNameChanged = valProjectName),
validator: (valProjectName) {
setState(() => _valueTaskNameToValidate = valProjectName);
return valProjectName.isEmpty? "Task name cannot be empty" : null;
},
onSaved: (valProjectName) => setState(() => _valueTaskNameSaved = valProjectName),
),
)),
//Test Energy et Time / Important /urgent
Material(
child:
Container(
// color: Colors.red,
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children:[
//Important
FlatButton(
child:
InkWell(
child: Container(
// color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
isImportant =="true" ? Icon(Icons.star,color: Colors.orange,) :
Icon(Icons.star_border, color: Colors.grey,),
// Icon(Icons.battery_charging_full),
Text('Important'),
],
)
),
onTap: () {
setState(() {
if (isImportant=='true'){
isImportant = 'false';}
else
{isImportant= 'true';
}
});
},
),
),
RaisedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
"Close",
style: TextStyle(color: Colors.white),
),
color: const Color(0xFF1BC0C5),
)
//++++++++++++++++
],
),
),
),
);
});
},
),
),
),
),
),
),
]
);
}).toList(),
);
}),
),
],
),
bottomNavigationBar: MyBottomAppBar(), //PersistentBottomNavBar(),
);
}
}
#override
Widget build(BuildContext context){
return _widget();
}
}
Thanks to your solution, I am able to do what I was willing to do. But now, I have an other issue. In the version 1 of my code, I am using this code
Theme(
data: ThemeData(
inputDecorationTheme: InputDecorationTheme(
border: InputBorder.none,
)
),
child: Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0.0, 15.0, 1.0),
child: TextFormField(
initialValue: document.data()['task_Name'],
decoration: InputDecoration(hintText: "Task Name"),
maxLength: 70,
maxLines: 2,
onChanged: (valProjectName) => setState(() => _valueTaskNameChanged = valProjectName),
validator: (valProjectName) {
setState(() => _valueTaskNameToValidate = valProjectName);
return valProjectName.isEmpty? "Task name cannot be empty" : null;
},
onSaved: (valProjectName) => setState(() => _valueTaskNameSaved = valProjectName),
),
)),
This part was working well. But after the modifications, I am getting an error. The error is about document.
Undefined name 'document'. Try correcting the name to one that is defined, or defining the name.
Please, can you help me with this so I can finalize this page. Thank you
So you want to change the color of icon on clicking it inside dialogBox,
but unfortunately you are using stateless widget Scaffold in return of showGeneralDialog builder so one thing that can possibly help is to make a separate StateFull Widget RatingDialogBox and use that in the builder.
Also instead of InkWell you can use IconButton
I will suggest you to use this package it is great
flutter_rating_bar
also feel free to comment is this doesn't satisfy your need

How can I create form modal with dropdown select in flutter

I am new to flutter and this is my first application. I have been trying to create a form modal with dropdown select would receive its data from the server. but for now I am using the values in array I created but it not setting the value after I select an item. I tried to add a setState() but is showing error. Please can someone help me?
Here is my code blow
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:erg_app/ProfilePage.dart';
void main() => runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
home: StockPage(),
)
);
class StockPage extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Inventory Data',
theme: ThemeData(
primarySwatch: Colors.green,
),
home: StockInventory(),
);
}
}
class StockInventory extends StatefulWidget {
StockInventory({Key key}) : super(key: key); //Find out meaning
#override
_StockInventoryState createState() => _StockInventoryState();
}
class _StockInventoryState extends State<StockInventory> {
List<Products> products;
List<Products> selectedProducts;
bool sort;
#override
void initState() {
sort = false;
selectedProducts = [];
products = Products.getProducts();
super.initState();
}
onSortColum(int columnIndex, bool ascending) {
if (columnIndex == 0) {
if (ascending) {
products.sort((a, b) => a.name.compareTo(b.name));
} else {
products.sort((a, b) => b.name.compareTo(a.name));
}
}
}
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: new Center(child: new Text('Daily Stock Taking', textAlign: TextAlign.center)),
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
backgroundColor: Colors.green,),
body: Container(
child: ListView(
children: <Widget>[
Container(
margin: const EdgeInsets.only(right: 20, top: 20),
child: Align(
alignment: Alignment.bottomRight,
child: RaisedButton(
padding: EdgeInsets.fromLTRB(14, 10, 14, 10),
color: Colors.green,
child: Text("Take Inventory", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 14), ),
onPressed: () {
// Navigator.of(context).push(MaterialPageRoute(builder: (context) => ProfilePage()));
showSimpleCustomDialog(context);
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
),
),
),
Container(
padding: EdgeInsets.only(top: 30, bottom: 30),
child: DataTable(
sortAscending: sort,
sortColumnIndex: 0,
columns: [
DataColumn(
label: Text("S/No", style: TextStyle(fontSize: 16)),
numeric: false,
),
DataColumn(
label: Text("Item", style: TextStyle(fontSize: 16)),
numeric: false,
onSort: (columnIndex, ascending) {
setState(() {
sort = !sort;
});
onSortColum(columnIndex, ascending);
}),
DataColumn(
label: Text("QtyInStock", style: TextStyle(fontSize: 16)),
numeric: false,
),
DataColumn(
label: Text("Unit", style: TextStyle(fontSize: 16)),
numeric: false,
),
],
rows: products
.map(
(product) => DataRow(
selected: selectedProducts.contains(product),
cells: [
DataCell(
Text(product.count),
onTap: () {
print('Selected ${product.count}');
},
),
DataCell(
Text(product.name),
onTap: () {
print('Selected ${product.name}');
},
),
DataCell(
Text(product.itemqty),
onTap: () {
print('Selected ${product.itemqty}');
},
),
DataCell(
Text(product.itemqty),
onTap: () {
print('Selected ${product.itemqty}');
},
),
]),
).toList(),
),
),
Container(
child: Center(
child: RaisedButton(
padding: EdgeInsets.fromLTRB(80, 10, 80, 10),
color: Colors.green,
child: Text("Post Inventory", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 14), ),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => ProfilePage()));
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
),
),
),
],
),
),
);
}
}
class Products {
String count;
String name;
String measuringunit;
String itemqty;
Products({this.count, this.name, this.itemqty, this.measuringunit});
static List<Products> getProducts() {
return <Products>[
Products(count:"1", name: "NPK Fertilizer", itemqty: "50", measuringunit: "bag",),
Products(count:"2", name: "Urea Fertilizer", itemqty: "560", measuringunit: "bag",),
Products(count:"3", name: "Spray", itemqty: "150", measuringunit: "bottles",),
];
}
}
void showSimpleCustomDialog(BuildContext context) {
String dropdownValue = 'SelectItem';
// TextEditingController _controller = TextEditingController(text: dropdownValue);
Dialog simpleDialog = Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child: Container(
height: 300.0,
width: 300.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top:20, bottom: 20, left: 30, right: 10),
child: Row(
children: <Widget>[
Expanded(child:
Text(
'Item',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, ),
),
),
Container(width: 2,),
Container(
child:DropdownButton<String>(
value: dropdownValue,
onChanged: (String newValue) {
// This set state is trowing an error
setState((){
dropdownValue = newValue;
});
},
items: <String>['Fertilizers', 'Bags', 'Spray', 'Equipments']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
})
.toList(),
),
),
],
)),
Padding(
padding: EdgeInsets.only(top:5, bottom: 5, left: 30, right: 10),
child: Row(
children: <Widget>[
Expanded(child:
Text(
'Quantity',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, ),
),
),
Container(width: 2,),
Expanded(child: TextField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Quantity',
hintText: 'Enter Cost Quantity',
border:OutlineInputBorder(borderRadius: BorderRadius.circular(5.0))
),
)),
],
)),
Padding(
padding: const EdgeInsets.only(left: 10, right: 10, top: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
RaisedButton(
color: Colors.blue,
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
'Add',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
),
SizedBox(
width: 20,
),
RaisedButton(
color: Colors.red,
onPressed: () {
Navigator.pop(context);
// Navigator.of(context).push(MaterialPageRoute(builder: (context) => StockPage()));
},
child: Text(
'Cancel!',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
)
],
),
),
],
),
),
);
showDialog(context: context, builder: (BuildContext context) => simpleDialog);
}
// Dropdown Menu Class below
Maybe I think that using the Statefulbuilder for the dialog. So you can change the state there just check the sample example.
Change as per you needs :
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: StockPage(),
));
class StockPage extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Inventory Data',
theme: ThemeData(
primarySwatch: Colors.green,
),
home: StockInventory(),
);
}
}
class StockInventory extends StatefulWidget {
StockInventory({Key key}) : super(key: key); //Find out meaning
#override
_StockInventoryState createState() => _StockInventoryState();
}
class _StockInventoryState extends State<StockInventory> {
List<Products> products;
List<Products> selectedProducts;
bool sort;
#override
void initState() {
super.initState();
sort = false;
selectedProducts = [];
products = Products.getProducts();
}
onSortColum(int columnIndex, bool ascending) {
if (columnIndex == 0) {
if (ascending) {
products.sort((a, b) => a.name.compareTo(b.name));
} else {
products.sort((a, b) => b.name.compareTo(a.name));
}
}
}
void showSimpleCustomDialog(BuildContext context) {
String dropdownValue ;
// TextEditingController _controller = TextEditingController(text: dropdownValue);
AlertDialog simpleDialog1 = AlertDialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(10.0))),
content: StatefulBuilder(
builder :(BuildContext context, StateSetter setState) {
return Container(
height: 300.0,
width: 300.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding:
EdgeInsets.only(top: 20, bottom: 20, left: 30, right: 10),
child: Row(
children: <Widget>[
Expanded(
child: Text(
'Item',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
Container(
width: 2,
),
Container(
child: DropdownButton<String>(
hint: Text('Enter value'),
value: dropdownValue,
onChanged: (String newValue) {
// This set state is trowing an error
setState(() {
dropdownValue = newValue;
});
},
items: <String>[
'Fertilizers',
'Bags',
'Spray',
'Equipments'
].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
),
),
],
)),
Padding(
padding:
EdgeInsets.only(top: 5, bottom: 5, left: 30, right: 10),
child: Row(
children: <Widget>[
Expanded(
child: Text(
'Quantity',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
Container(
width: 2,
),
Expanded(
child: TextField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Quantity',
hintText: 'Enter Cost Quantity',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0))),
)),
],
)),
Padding(
padding: const EdgeInsets.only(left: 10, right: 10, top: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
RaisedButton(
color: Colors.blue,
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
'Add',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
),
SizedBox(
width: 20,
),
RaisedButton(
color: Colors.red,
onPressed: () {
Navigator.pop(context);
// Navigator.of(context).push(MaterialPageRoute(builder: (context) => StockPage()));
},
child: Text(
'Cancel!',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
)
],
),
),
],
),
);
}
),
);
/* Dialog simpleDialog = Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child:
); */
showDialog(
context: context, builder: (BuildContext context) => simpleDialog1);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: new Center(
child: new Text('Daily Stock Taking', textAlign: TextAlign.center)),
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
backgroundColor: Colors.green,
),
body: Container(
child: ListView(
children: <Widget>[
Container(
margin: const EdgeInsets.only(right: 20, top: 20),
child: Align(
alignment: Alignment.bottomRight,
child: RaisedButton(
padding: EdgeInsets.fromLTRB(14, 10, 14, 10),
color: Colors.green,
child: Text(
"Take Inventory",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14),
),
onPressed: () {
// Navigator.of(context).push(MaterialPageRoute(builder: (context) => ProfilePage()));
showSimpleCustomDialog(context);
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
),
),
),
Container(
padding: EdgeInsets.only(top: 30, bottom: 30),
child: DataTable(
sortAscending: sort,
sortColumnIndex: 0,
columns: [
DataColumn(
label: Text("S/No", style: TextStyle(fontSize: 16)),
numeric: false,
),
DataColumn(
label: Text("Item", style: TextStyle(fontSize: 16)),
numeric: false,
onSort: (columnIndex, ascending) {
setState(() {
sort = !sort;
});
onSortColum(columnIndex, ascending);
}),
DataColumn(
label: Text("QtyInStock", style: TextStyle(fontSize: 16)),
numeric: false,
),
DataColumn(
label: Text("Unit", style: TextStyle(fontSize: 16)),
numeric: false,
),
],
rows: products
.map(
(product) => DataRow(
selected: selectedProducts.contains(product),
cells: [
DataCell(
Text(product.count),
onTap: () {
print('Selected ${product.count}');
},
),
DataCell(
Text(product.name),
onTap: () {
print('Selected ${product.name}');
},
),
DataCell(
Text(product.itemqty),
onTap: () {
print('Selected ${product.itemqty}');
},
),
DataCell(
Text(product.itemqty),
onTap: () {
print('Selected ${product.itemqty}');
},
),
]),
)
.toList(),
),
),
Container(
child: Center(
child: RaisedButton(
padding: EdgeInsets.fromLTRB(80, 10, 80, 10),
color: Colors.green,
child: Text(
"Post Inventory",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14),
),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => ProfilePage()));
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
),
),
),
],
),
),
);
}
}
class Products {
String count;
String name;
String measuringunit;
String itemqty;
Products({this.count, this.name, this.itemqty, this.measuringunit});
static List<Products> getProducts() {
return <Products>[
Products(
count: "1",
name: "NPK Fertilizer",
itemqty: "50",
measuringunit: "bag",
),
Products(
count: "2",
name: "Urea Fertilizer",
itemqty: "560",
measuringunit: "bag",
),
Products(
count: "3",
name: "Spray",
itemqty: "150",
measuringunit: "bottles",
),
];
}
}
class ProfilePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container();
}
}
Just check the code.
Let me know if it works

Textfield returning null; bypassing await

Im making a counter app and want to be able to change the title of the appbar by taking input from the user using an popup input box.
I am trying to have the user input a name(string) in an AlertDialog with textfield in it and trying to recieve the string in the main page by defining a function for the popup which returns the inputted string when confirm button is pressed. I'm assigning a variable to this function using await in the onPressed() of the main page and then displaying the string variable change in a snackbar. however, the snackbar is appearing as soon i tap on the textfield without even submitting or hitting the confirm button. it looks like either the await isnt working or for some reason the Alertdialog's parent function is returning null as soon as I tap on the textfield.
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(
home: CounterApp(),
));
class CounterApp extends StatefulWidget {
#override
_CounterAppState createState() => _CounterAppState();
}
class _CounterAppState extends State<CounterApp> {
int num = 0;
String name = 'MyCounter-1';
Future<String> changeName() async {
final _controller = TextEditingController();
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)
),
title: Text('Change counter name'),
content: TextField(
controller: _controller,
onSubmitted: (str) {
//Navigator.of(context).pop(str);
},
),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).pop(_controller.text.toString());
},
child: Text(
'Confirm',
style: TextStyle(
fontSize: 18.0,
),
),
),
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
'Cancel',
style: TextStyle(
fontSize: 18.0,
),
),
),
],
);
},
);
}
void snackBar(BuildContext context, String string) {
final snackbar = SnackBar(content: Text('Counter renamed to $string'),);
Scaffold.of(context).showSnackBar(snackbar);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(name),
centerTitle: true,
actions: <Widget>[
IconButton(
onPressed: () {
setState(() {
num = 0;
});
},
icon: Icon(
Icons.refresh,
size: 35.0,
),
),
Builder(
builder: (context) => IconButton(
onPressed: () async {
setState(() async {
name = await changeName();
snackBar(context, name);
});
},
icon: Icon(
Icons.edit,
size: 35.0,
),
),
),
],
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
flex: 2,
child: Container(
child: Center(child: Text(
'$num',
style: TextStyle(
fontSize: 75,
),
)),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 10),
child: RaisedButton(
onPressed: () {
setState(() {
num += 1;
});
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0)
),
color: Colors.blue,
child: Text(
'+',
style: TextStyle(
fontSize: 100.0,
),
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 20),
child: RaisedButton(
onPressed: () {
setState(() {
num -= 1;
});
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0)
),
color: Colors.grey,
child: Text(
'-',
style: TextStyle(
fontSize: 100.0,
),
),
),
)
],
),
);
}
}
As Soon as I tap on the edit button, this happens:
Image of problem
Just Add await keyword before showDialog() and add return statement at last as shown in the below code.
Future<String> changeName() async {
final _controller = TextEditingController();
await showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
title: Text('Change counter name'),
content: TextField(
controller: _controller,
onSubmitted: (str) {
//Navigator.of(context).pop(str);
},
),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).pop(_controller.text.toString());
},
child: Text(
'Confirm',
style: TextStyle(
fontSize: 18.0,
),
),
),
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
'Cancel',
style: TextStyle(
fontSize: 18.0,
),
),
),
],
);
},
);
return _controller.text;
}