Navigator.pop shows me a black screen - flutter

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;
}

Related

Flutter Inkwell Ontap not working inside a Stack

I am building a flutter ecommerce app and I am having an issue where ontap isn't working inside my inkwell widget. I want the ontap to work so that I can show the product description. I have placed the inkwell widget as a child inside a Positioned widget, which happens to be one of the children of a Stack. How can I solve this?
Here's my code:
return Card(
shadowColor: Colors.grey,
surfaceTintColor: Colors.amber,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
child: Stack(
children: [
Positioned(
right: 0,
child: InkWell(
onTap: () {
print('tapped');
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ProductDetails(
id: bottleCategory
.bottleList[index].id,
bottleName: bottleCategory
.bottleList[index]
.bottleName,
image: bottleCategory
.bottleList[index]
.image,
price: bottleCategory
.bottleList[index]
.price)));
},
child: IconButton(
icon: favoriteProvider.isExist(
bottleCategory.bottleList[index])
? Icon(
Icons.favorite,
color: Colors.redAccent,
)
: Icon(
Icons.favorite_border,
),
onPressed: (() {
favoriteProvider.toggleFavorites(
bottleCategory.bottleList[index]);
if (favoriteProvider.isExist(
bottleCategory.bottleList[index])) {
ScaffoldMessenger.of(context)
.hideCurrentSnackBar();
ScaffoldMessenger.of(context)
.showSnackBar(
const SnackBar(
content: Text(
"Product Added to Favorite!",
style: TextStyle(fontSize: 16),
),
backgroundColor: Colors.green,
duration: Duration(seconds: 1),
),
);
} else {
ScaffoldMessenger.of(context)
.hideCurrentSnackBar();
ScaffoldMessenger.of(context)
.showSnackBar(
const SnackBar(
content: Text(
"Product Removed from Favorite!",
style: TextStyle(fontSize: 16),
),
backgroundColor: Colors.red,
duration: Duration(seconds: 1),
),
);
}
}),
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Image.asset(
bottleCategory.bottleList[index].image,
height: 200.0,
),
),
Center(
child: Text(
bottleCategory
.bottleList[index].bottleName,
style: const TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold))),
Center(
child: Text(
'R${bottleCategory.bottleList[index].price}'),
)
],
),
Positioned(
bottom: 0,
right: 10,
child: IconButton(
icon: const Icon(Icons.add_circle),
iconSize: 40.0,
onPressed: () {
cart.addToCart(
bottleCategory.bottleList[index].id,
bottleCategory
.bottleList[index].bottleName,
bottleCategory
.bottleList[index].price,
bottleCategory
.bottleList[index].image);
},
))
],
),
);
Why do you use IconButton in the child of InkWell?
use one of them and Put all of your onPress functions into that widget.

Error : The argument type 'Context' can't be assigned to the parameter type 'BuildContext'

There was a problem with my code, while I was trying to exit a screen of mine from my bus tracking app main page but this is showing an error. I have tried importing everything given in StackOverflow.
help me to get this solved please
import 'dart:js';
import 'package:flutter/services.dart';
import 'registration_screen.dart';
import 'login_screen.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:path/path.dart';
class WelcomePage extends StatelessWidget {
From here the function starts
Future<bool?> _onBackPressed() async {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(`enter code here`
title: Text('Do you want to exit?'),
actions: <Widget>[
TextButton(
child: Text('No'),
onPressed: () {
Navigator.of(context).pop(false);
},
),
TextButton(
child: Text('Yes'),
onPressed: () {
Navigator.of(context).pop(true);
SystemNavigator.pop();
},
),
],
);
}
);
}
Scaffold start here also the WillPopScope starts here which returns the _onBackPressed();
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
bool? result = await _onBackPressed();
if (result == null) {
result = false;
}
return result;
},
child: Scaffold(
// return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
Flexible(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
height: 20,
),
Lottie.asset('assets/images/bus.json'),
SizedBox(
height: 20,
),
Text(
"Welcome to \n Bus Tracking",
style: GoogleFonts.poppins(
fontSize: 34, fontWeight: FontWeight.w700),
textAlign: TextAlign.center,
),
],
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 38),
child: Container(
height: 65,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.3),
spreadRadius: 2,
blurRadius: 3,
offset: Offset(0, 5))
],
color: Colors.deepPurple,
borderRadius: BorderRadius.circular(12),
),
child: Row(
children: [
Expanded(
child: GestureDetector(
onTap: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) =>
RegistrationScreen()));
},
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.deepPurple,
width: 0.9,
)
//textColor: Colors.black87,
),
child: const Center(
child: Text(
'Register',
style: TextStyle(
color: Colors.deepPurple,
fontWeight: FontWeight.bold,
fontSize: 15,
),
),
),
),
),
),
Expanded(
child: GestureDetector(
//bgColor: Colors.transparent,
//buttonName: 'Sign In',
onTap: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => LoginScreen(),
));
},
child: Container(
decoration: BoxDecoration(
color: Colors.deepPurple,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.deepPurple,
width: 0.9,
)
//textColor: Colors.black87,
),
child: const Center(
child: Text(
'Login',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 15,
),
),
),
),
),
),
],
),
),
),
],
),
),
),
));
}
}
Change the function _onBackPressed as
Future<bool?> _onBackPressed(BuildContext ctx) async {
return showDialog(
context: ctx,
builder: (BuildContext context) {
return AlertDialog(`enter code here`
title: Text('Do you want to exit?'),
actions: <Widget>[
TextButton(
child: Text('No'),
onPressed: () {
Navigator.of(context).pop(false);
},
),
TextButton(
child: Text('Yes'),
onPressed: () {
Navigator.of(context).pop(true);
SystemNavigator.pop();
},
),
],
);
}
);
}
Now in the build function use :
bool? result = await _onBackPressed(context);
context is getting clashed may de due to import 'package:path/path.dart'; if you don't need it remove it.
Here in the question i have been using a stateless widget but I need to use a stateful widget, so the solution is to create a new file as a stateful widget and dumb all this code in it and the error was solved.

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

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

Flutter problem with saving the value from document from database to a initState value

I have a problem with fetching value from database document to a variable called in initState method. When I am doing that there is a problem with null value and I think that get() method from Firebase is taking the value too late(it happens when i reload the scene).
bool _dark;
bool options;
MainModel model;
final MyUser myUser;
final UserSettings userSettings;
_SettingsOnePageState(this.userSettings, this.myUser);
final user = FirebaseAuth.instance.currentUser;
#override
void initState() {
super.initState();
// _dark = false;
FirebaseFirestore.instance
.collection("settings")
.doc(user.uid)
.get()
.then((value) {
print(value.data()['darkMode']);
_dark = value.data()['darkMode'];
});
options = false;
}
Brightness _getBrightness() {
return _dark ? Brightness.dark : Brightness.light;
}
#override
Widget build(BuildContext context) {
return Theme(
// return StreamProvider<QuerySnapshot>.value(
isMaterialAppTheme: true,
data: ThemeData(
brightness: _getBrightness(),
),
// value: SettingsUser().settings,
child: StreamBuilder<UserSettings>(
//setting the stream for settings from database
stream: DatabaseUser(userId: user.uid).userData,
builder: (context, snapshot) {
if (snapshot.hasData) {
//data for user from database
UserSettings userSettings = snapshot.data;
// _dark = userSettings.darkMode;
// print("dark mode " + userSettings.darkMode.toString());
return Form(
key: _formKey,
child: Scaffold(
backgroundColor: _dark ? null : Colors.grey.shade200,
appBar: AppBar(
//elevation: 10,
brightness: _getBrightness(),
iconTheme: IconThemeData(
color: _dark ? Colors.white : Colors.black),
backgroundColor: Colors.transparent,
title: Text(
'Change theme',
style: TextStyle(
color: _dark ? Colors.white : Colors.black),
textAlign: TextAlign.center,
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.auto_awesome),
onPressed: () {
setState(() {
_dark = !_dark;
});
},
)
],
),
body: Stack(fit: StackFit.expand, children: <Widget>[
SingleChildScrollView(
//padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Stack(
children: <Widget>[
Align(
alignment: Alignment.center,
child: Text(
userSettings.nick,
textScaleFactor: 4,
style: TextStyle(
color: _dark
? Colors.white
: Colors.purple[500],
//fontWeight: FontWeight.w500,
),
)),
const SizedBox(height: 50.0),
],
),
Stack(
children: <Widget>[
Align(
alignment: Alignment.center,
child: Container(
// width: 200,
// height: 200,
child: CircleAvatar(
radius: 100.0,
backgroundImage:
//NetworkImage(user.photoURL),
NetworkImage(
userSettings.pictureUrl),
),
),
),
],
),
//const SizedBox(height: 20.0),
if (options == true) ...[
//SettingsEdit(),
//NickChange(),
ImageInput(),
],
const SizedBox(height: 10.0),
Card(
elevation: 4.0,
margin: const EdgeInsets.fromLTRB(
32.0, 8.0, 32.0, 16.0),
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(10.0)),
child: Column(
children: <Widget>[
ListTile(
leading: Icon(
Icons.account_box,
color: Colors.purple,
),
title: Text("Change Nickname"),
trailing:
Icon(Icons.keyboard_arrow_right),
onTap: () {
//open change nick
//changeNick();
},
),
_buildDivider(),
ListTile(
leading: Icon(
Icons.add_a_photo,
color: Colors.purple,
),
title: Text("Change Photo"),
trailing:
Icon(Icons.keyboard_arrow_right),
onTap: () {
//open change photo
//changePhoto();
},
),
_buildDivider(),
ListTile(
leading: Icon(
Icons.lock_rounded,
color: Colors.purple,
),
title: Text("Change Password"),
trailing:
Icon(Icons.keyboard_arrow_right),
onTap: () {
//open change password
//changePassword();
},
),
_buildDivider(),
ListTile(
leading: Icon(
Icons.location_on,
color: Colors.purple,
),
title: Text("Change Your Location"),
trailing:
Icon(Icons.keyboard_arrow_right),
onTap: () {
//open change location
},
),
],
),
),
const SizedBox(height: 20.0),
]))
])));
}
return Scaffold();
}));
}
debug console
settings where I use theme now
Do you know how to avoid this null in initState? I am trying to change theme of the app and I am taking that from Firebase document whick I created when the user registered. Than I will be changing it in user settings and also want to use it(this theme) in whole app.
Thanks for help
InitState is not async (meaning execution doesn't wait for your firebase call to complete). This means that your view will be rendered before you assign _dark a value.
If you want to wait until that call is complete, use something called FutureBuilder.

Selecting a specific BottomNavigationBar when routing from another widget (Flutter)

Please, help. This is my first project using Flutter. I am making an app for pets.
I have Homepage widget that has 4 bottom Navbar (Home, Photos, Medical, Profile). In Profile I have a button "About", which opens a widget about us.
But when I am trying to return to back from About, it returns to "Home" NavBottombar. I am trying to select Profile NavBottomBar.
I think that is related to current index in Homepage, which equals 0 at the beginning. But how can I change from 0 to 2 while routing?
homepage.dart
import 'package:flutter/material.dart';
import 'placeholder_widget.dart';
import 'dashboard.dart';
import 'medical.dart';
import 'profile.dart';
import 'about.dart';
void main() => runApp(MaterialApp(
home: Homepage(),
));
class Homepage extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<Homepage> {
int _currentIndex = 0;
final List<Widget> _children = [
Dashboard(),
PlaceholderWidget(Colors.deepOrange),
PlaceholderWidget(Colors.red),
// Medical(),
Profile()
];
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Furball Tales'),
backgroundColor: Colors.cyanAccent[400],
),
body: _children[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
onTap: onTabTapped,
currentIndex: _currentIndex,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.perm_media),
title: Text('Photos'),
),
BottomNavigationBarItem(
icon: Icon(Icons.local_hospital),
title: Text('Medical'),
),
BottomNavigationBarItem(
icon: Icon(Icons.perm_identity),
title: Text('Profile'),
),
],
selectedItemColor: Colors.cyanAccent[400],
unselectedItemColor: Colors.grey[600],
),
),
);
}
void onTabTapped(int index) {
setState(() {
_currentIndex = index;
});
}
}
about.dart
import 'package:flutter/material.dart';
import 'profile.dart';
import 'homepage.dart';
class About extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('About FurBallTales'),
backgroundColor: Colors.cyanAccent[400],
leading: GestureDetector(
onTap: () {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) {
return Homepage();
}), ModalRoute.withName('/'));
},
child: Icon(
Icons.arrow_back,
)),
),
body: ListView(
padding: const EdgeInsets.all(2),
children: <Widget>[
Container(
decoration:
BoxDecoration(border: Border.all(color: Colors.blueAccent)),
child: Column(
children: <Widget>[
Container(
height: 30,
margin: EdgeInsets.all(5),
child: Text(
'OUR MISSION',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.tealAccent[400]),
),
),
Container(
height: 25,
margin: EdgeInsets.all(5),
child: Text(
'Strengthening the bond of owners and pets, more than ever',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold, color: Colors.black),
),
),
],
),
),
Container(
height: 50,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 50,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
],
),
);
}
}
profile.dart
import 'package:flutter/material.dart';
import 'sign_in.dart';
import 'login_page.dart';
import 'about.dart';
import 'donation.dart';
class Profile extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircleAvatar(
radius: 80,
backgroundImage: NetworkImage(
'https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcSxDoD5caxFUy_dn0w6wl01m882CeJHNVOCRg&usqp=CAU'),
),
Text(
'<$name>',
style: TextStyle(
fontFamily: 'SourceSansPro',
fontSize: 25,
),
),
Text(
'<$email>',
style: TextStyle(
fontSize: 20,
fontFamily: 'SourceSansPro',
color: Colors.red[400],
letterSpacing: 2.5,
),
),
SizedBox(
height: 20.0,
width: 200,
child: Divider(
color: Colors.teal[200],
),
),
// this is about page-----------------------------------------
InkWell(
onTap: () {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) {
return About();
}), ModalRoute.withName('/about'));
},
child: Card(
color: Colors.white,
margin:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 25.0),
child: ListTile(
leading: Icon(
Icons.help,
color: Colors.teal[900],
),
title: Text(
'About',
style:
TextStyle(fontFamily: 'BalooBhai', fontSize: 20.0),
),
)),
),
InkWell(
onTap: () {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) {
return Donation();
}), ModalRoute.withName('/about'));
},
child: Card(
color: Colors.white,
margin:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 25.0),
child: ListTile(
leading: Icon(
Icons.monetization_on,
color: Colors.teal[900],
),
title: Text(
'Donation',
style: TextStyle(fontSize: 20.0, fontFamily: 'Neucha'),
),
),
),
),
InkWell(
onTap: () {
signOutGoogle();
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) {
return LoginPage();
}), ModalRoute.withName('/'));
},
child: Card(
color: Colors.white,
margin:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 25.0),
child: ListTile(
leading: Icon(
Icons.account_circle,
color: Colors.teal[900],
),
title: Text(
'LOGOUT',
style: TextStyle(fontSize: 20.0, fontFamily: 'Neucha'),
),
),
),
),
],
),
),
),
);
}
}
Instead of using pushAndRemoveUntil in your About page, you can use Navigator.pop(context)( which removes the view from the Navigator stack):
I added a demo using your code as an example:
class About extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('About FurBallTales'),
backgroundColor: Colors.cyanAccent[400],
leading: GestureDetector(
onTap: () {
Navigator.pop(context); // pop the view
},
child: Icon(
Icons.arrow_back,
)),
),
...
);
}
}
NOTE:
With this approach, the state of the BottomNavigationBar is reserved.
Thank you for everyone, who helped me.
The problem has been solved this way:
First, I pushed to new page.
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => About()));
}
Then made pop context.
onTap: () {
Navigator.pop(context);
},
It returned initial position.
Where it says return Homepage(); in about.dart you could change that to return the profile widget.