Flutter: Prevent Future Builder from firing - flutter

I am new to flutter and I'm trying to build a simple app. Whenever I update profile details from EditProfileScreen and try to return to ProfileScreen through LandingScreen, FutureBuilder keeps on firing and LogoScreen appears. How to avoid that?
I tried of using Navigator pop but my new data is not updated in that case. I can't Navigate to ProfileScreen directly as I don't want to loose my bottom navigation bar. Can anybody suggest me a right way to do this?
LandingScreen():
class LandingScreen extends StatefulWidget {
final int index;
LandingScreen({this.index});
#override
_LandingScreenState createState() => _LandingScreenState();
}
class _LandingScreenState extends State<LandingScreen> {
int _currentIndex = 0;
List<Futsal> list;
List<Search> listHistory;
List<Futsal> futsalList;
Future<dynamic> loadDataFuture;
final List<Widget> _children = [
HomePage(),
ExploreScreen(),
ProfileDetails(),
];
#override
void initState() {
onTappedBar(widget.index);
loadDataFuture = getFutureData();
super.initState();
}
void onTappedBar(int index) {
setState(() {
_currentIndex = index;
});
}
Future getFutureData() async {
listHistory = await fetchSearchs();
futsalList = await fetchFutsals();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: new FutureBuilder(
future: loadDataFuture,
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return new Text('Please close the application and Try Again.');
case ConnectionState.waiting:
return LogoScreen();
default:
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
else
return Scaffold(
backgroundColor: Colors.white,
appBar: new AppBar(
automaticallyImplyLeading: false,
backgroundColor: kPrimaryLightColor,
title: Text(
'letsfutsal',
style: TextStyle(
fontWeight: FontWeight.bold,
color: kPrimaryColor,
),
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
color: kPrimaryColor,
onPressed: () {
showSearch(
context: context,
delegate: SearchScreen(
futsalList: futsalList,
listHistory: listHistory));
},
),
],
),
body: _children[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
onTap: onTappedBar,
currentIndex: _currentIndex,
selectedItemColor: kPrimaryColor,
unselectedItemColor: Colors.black38,
showSelectedLabels: false,
showUnselectedLabels: false,
items: [
BottomNavigationBarItem(
icon: new FaIcon(FontAwesomeIcons.home),
title: new Text(''),
),
BottomNavigationBarItem(
icon: FaIcon(FontAwesomeIcons.safari),
title: Text(''),
),
BottomNavigationBarItem(
icon: FaIcon(FontAwesomeIcons.solidUserCircle),
title: Text(''),
),
],
),
);
}
},
),
);
}
}
ProfileScreen():
class ProfileDetails extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => CustomUserProvider()),
ChangeNotifierProvider(create: (context) => MyBookingsProvider()),
],
child: SafeArea(
child: Scaffold(
backgroundColor: kPrimaryLightColor,
appBar: new AppBar(
automaticallyImplyLeading: false,
elevation: 0,
title: Text(
'Profile',
style: TextStyle(
fontWeight: FontWeight.bold,
color: kPrimaryColor,
),
),
actions: [
FlatButton.icon(
onPressed: () {},
icon: Icon(
FontAwesomeIcons.signOutAlt,
color: kPrimaryColor,
),
label: Text(
'Log Out',
style: TextStyle(
color: kPrimaryColor,
),
),
),
],
),
body: new Container(
padding: const EdgeInsets.all(15.0),
child: new Center(
child: new Column(
children: <Widget>[
UserDetails(),
MyBookingsList(),
],
),
),
),
),
),
);
}
}
class UserDetails extends StatelessWidget {
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
final userProvider = Provider.of<CustomUserProvider>(context);
if (userProvider.user.length == 0) {
return Container();
} else {
return Column(
children: <Widget>[
new CircularImageContainer(
radius: 50,
imageUrl: "assets/images/profile.png",
),
SizedBox(height: size.height * 0.03),
Text(
userProvider.user[0].name != null ? userProvider.user[0].name : "",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
SizedBox(height: size.height * 0.01),
Text(
userProvider.user[0].address != null
? userProvider.user[0].address
: "",
),
FlatButton.icon(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return EditProfileScreen(
user: userProvider.user[0],
);
},
),
);
},
icon: Icon(
Icons.edit,
color: kPrimaryColor,
),
label: Text(
'Edit Profile',
style: TextStyle(
color: kPrimaryColor,
),
),
),
],
);
}
}
}
class MyBookingsList extends StatelessWidget {
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
final bookingsProvider = Provider.of<MyBookingsProvider>(context);
if (bookingsProvider.bookings.length == 0) {
return Container();
} else {
return Column(
children: <Widget>[
ScrollListContainer(
text: "My Bookings",
size: size,
),
ListView.builder(
shrinkWrap: true,
itemCount: bookingsProvider.bookings.length,
scrollDirection: Axis.vertical,
physics: BouncingScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
return Card(
child: Container(
width: 150,
child: ExpansionTile(
title: Text(
index.toString() +
'. ' +
bookingsProvider
.bookings[index].futsal.customUser.name !=
null
? bookingsProvider
.bookings[index].futsal.customUser.name
: "",
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
children: <Widget>[
ListTile(
title: Text(
bookingsProvider.bookings[index].status,
),
subtitle: Text(
'For ' + bookingsProvider.bookings[index].bookedFor,
),
dense: true,
),
],
),
),
);
},
),
],
);
}
}
}
EditProfileScreen():
class EditProfileScreen extends StatefulWidget {
final CustomUser user;
EditProfileScreen({this.user});
#override
_EditProfileScreenState createState() => new _EditProfileScreenState();
}
class _EditProfileScreenState extends State<EditProfileScreen> {
final scaffoldKey = new GlobalKey<ScaffoldState>();
final formKey = new GlobalKey<FormState>();
String _name;
String _address;
#override
void initState() {
super.initState();
}
#override
void dispose() {
super.dispose();
}
void _submit() {
final form = formKey.currentState;
if (form.validate()) {
form.save();
performUpdate();
}
}
void performUpdate() async {
Map data = {
'name': _name,
'address': _address,
};
var url =MY_URL;
var response = await http.post(url,
headers: {"Accept": "application/json"}, body: data);
print(response.body);
if (response.statusCode == 200) {
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (BuildContext context) => LandingScreen(index: 2,)));
}
}
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return new SafeArea(
child: Scaffold(
key: scaffoldKey,
backgroundColor: Colors.white,
appBar: AppBar(
centerTitle: true,
// automaticallyImplyLeading: false,
leading: BackButton(
color: kPrimaryColor,
),
elevation: 0,
backgroundColor: kPrimaryLightColor,
title: Text(
widget.user.name,
style: TextStyle(
fontWeight: FontWeight.bold,
color: kPrimaryColor,
),
),
),
body: new Container(
height: size.height,
width: double.infinity,
padding: const EdgeInsets.all(30.0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Edit Details",
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: size.height * 0.03),
new Form(
key: formKey,
child: new Column(
children: <Widget>[
new TextFieldContainer(
child: new TextFormField(
controller:
TextEditingController(text: widget.user.name),
decoration: new InputDecoration(
labelText: "Name",
icon: Icon(
Icons.person,
color: kPrimaryColor,
),
border: InputBorder.none,
),
validator: (val) =>
val.isEmpty ? 'Please enter name' : null,
onSaved: (val) => _name = val,
),
),
new TextFieldContainer(
child: new TextFormField(
controller: TextEditingController(
text: widget.user.address != null
? widget.user.address
: ''),
decoration: new InputDecoration(
labelText: "Address",
icon: Icon(
Icons.email,
color: kPrimaryColor,
),
border: InputBorder.none,
),
validator: (val) =>
val.isEmpty ? 'Please enter your address' : null,
onSaved: (val) => _address = val,
),
),
RoundedButton(
text: "Update",
press: _submit,
),
],
),
),
],
),
),
),
),
);
}
}

As you are using Provider, you can do something like this.
#override
void initState() {
bloc = Provider.of<MyDealsBLOC>(context, listen: false);
if (!bloc.isLoaded) {
Future.delayed(
Duration.zero,
() => Provider.of<MyDealsBLOC>(context, listen: false).loadData(),
);
bloc.isLoaded = true;
print('IsLoaded: ${bloc.isLoaded}');
}
super.initState();
}
What I did is that I use a boolean isLoaded in my bloc to check whether data has been loaded once or not. I beleive you can do the same as well.

If you are trying to prevent a network image from keep downloading and loading you need to use cached_network_image to cache the image and it won't download again. Just put in the image download URL and the package will do the rest.

Related

flutter How to update bool data using switchlisttile to cloudfirestore

I want to save boolean values to Firebase cloud firestore in switchlisttile section. I'm very new to flutter. I want to save boolean values to cloud firestore.
when I choose to switchtile on or off I want the on or off value to be boolean and save to firestore
I've been stuck on this issue for a very long time now and I can't seem to find a solution to it.
class Dashboard_Screen extends StatefulWidget {
#override
State<Dashboard_Screen> createState() => _Dashboard_ScreenState();
}
class _Dashboard_ScreenState extends State<Dashboard_Screen> {
//switch settingpage
bool _isSwitchedOn_water = false;
bool _isSwitchedOn_liquidfertilizer = false;
bool _isSwitchedOn_light = false;
//controlpage
int _currentIndex = 0;
late PageController _pageController;
//set initstate
#override
void initState() {
super.initState();
_pageController = PageController();
}
// dispose
void dispose() {
_pageController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
// drawer: Navigationbar(),
appBar: AppBar(
title: Text('Dashboard'),
backgroundColor: Colors.green.shade900,
actions: [
IconButton(
onPressed: (() {
}),
icon: Icon(Icons.settings),
)
]),
body: StreamBuilder(
stream:
FirebaseFirestore.instance.collection("outputtest").snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
return Scaffold(
body: PageView(
controller: _pageController,
onPageChanged: (index) {
setState(() {
_currentIndex = index;
});
},
children: [
//set page
//PAGE DASHBOARD
****
// PAGE SETTING
// ---------------page setting-----------//
SingleChildScrollView(
child: Column(
children: [
const SizedBox(
height: 20,
),
Center(
child: SwitchListTile(
activeColor: Colors.green.shade600,
title: Text(
_isSwitchedOn_water ? 'water' : 'water',
style: TextStyle(
fontSize: 20,
),
),
subtitle: (Text(
_isSwitchedOn_water ? 'on' : 'off',
style: TextStyle(
fontSize: 16,
),
)),
value: _isSwitchedOn_water,
onChanged: (bool value) {
setState(() {
_isSwitchedOn_water = value;
(print(value));
});
},
secondary: const Icon(Icons.water_drop),
),
),
Center(
child: SwitchListTile(
activeColor: Colors.green.shade600,
title: Text(
_isSwitchedOn_liquidfertilizer
? 'liquidfertilizer'
: 'liquidfertilizer',
style: TextStyle(
fontSize: 20,
),
),
subtitle: (Text(
_isSwitchedOn_liquidfertilizer ? 'on' : 'off',
style: TextStyle(
fontSize: 16,
),
)),
value: _isSwitchedOn_liquidfertilizer,
onChanged: (bool value) {
setState(() {
_isSwitchedOn_liquidfertilizer = value;
(print(value));
});
},
secondary: const Icon(Icons.water_outlined),
),
),
Center(
child: SwitchListTile(
activeColor: Colors.green.shade600,
title: Text(
_isSwitchedOn_light ? 'lightbulb' : 'lightbulb',
style: TextStyle(
fontSize: 20,
),
),
subtitle: (Text(
_isSwitchedOn_light ? 'on' : 'off',
style: TextStyle(
fontSize: 16,
),
)),
value: _isSwitchedOn_light,
onChanged: (bool value) {
setState(() {
_isSwitchedOn_light = value;
(print(value));
// (print(_isSwitchedOn_light));
});
},
secondary: const Icon(Icons.lightbulb),
),
),
],
),
)
],
),
//Gnav googlesizebar importจาก pub.dev
bottomNavigationBar: Container(
color: Colors.green.shade900,
child: Padding(
padding: const EdgeInsets.all(0.0),
child: GNav(
onTabChange: (index) {
setState(() {
_pageController.jumpToPage(index);
});
},
backgroundColor: Colors.green.shade900,
color: Colors.white,
activeColor: Colors.white,
tabBackgroundColor: Colors.green.shade800,
tabBorderRadius: 15,
iconSize: 20,
gap: 30,
tabs: [
GButton(icon: Icons.dashboard, text: " dashboard"),
// GButton(icon: Icons.settings, text: " setting"),
]),
),
),
);
}));
}
}
FirebaseFirestore.instance
.collection('orders')
.where('id', isEqualTo: order.id)
.get()
.then((querySnapshot) => {
querySnapshot.docs.first.reference.update({field: newValue})
});
here replace orders with your own collection reference key, and replace order.id with your switch id, and replace field with your firebase field name. newValue will be true or false as your need.

How to save data locally using shared preferences

i want save data locally in device, when i will terminate my app and when i will reopen i want my previous data to be stored locally.so how i can save that using shared preferences in flutter
here my home page where i set value:
import 'package:flutter/material.dart';
import 'package:list_ex/product.dart';
import 'package:sizer/sizer.dart';
import 'package:list_ex/info.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'shared_pref.dart';
class Myhome extends StatefulWidget {
const Myhome({Key? key}) : super(key: key);
#override
State<Myhome> createState() => _MyhomeState();
}
class _MyhomeState extends State<Myhome> {
List <Data> productdata = [];
final myController = TextEditingController();
TextEditingController productController = TextEditingController();
TextEditingController prizeController = TextEditingController();
late SharedPreferences sharedPreferences;
#override
void initState() {
// TODO: implement initState
super.initState();
getprodata();
getpridata();
#override
void dispose() {
// Clean up the controller when the widget is disposed.
myController.dispose();
super.dispose();
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Products',
style: TextStyle(
fontSize: 30.0,
),
),
centerTitle: true,
backgroundColor: Colors.grey[800],
actions: [
IconButton(onPressed: () {
showDialog(context: context, builder: (context) =>
Dialog(
child: SizedBox(
height: 200,
width: 200,
child: Column(
children: [
TextFormField(
decoration: InputDecoration(
filled: true,
labelText: 'product',
icon: Icon(Icons.star),
),
controller: productController,
validator: (value){
if(value == null || value.isEmpty){
return 'Enter product name';
}
return null;
},
),
Divider(
height: 20.0,
color: Colors.grey[800],
),
///Text Field
TextFormField(
decoration: InputDecoration(
filled: true,
labelText: 'price',
icon: Icon(Icons.star),
),
keyboardType: TextInputType.number,
controller: prizeController,
),
ElevatedButton(onPressed: () {
if (productController.text.isEmpty && prizeController.text.isEmpty){
const AlertDialog(
title: Text('Enter Value'),
);
} else{
setState(() {
setprodata(productController.text);
setpridata(prizeController.text);
productdata.add(Data(productController.text, prizeController.text));
productController.text = "";
prizeController.text = "";
Navigator.of(context).pop();
});
}
}, child:
const Text('Submit')),
],
),
),
),
);
}, icon: Icon(Icons.add))
],
),
///app Drawer
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
UserAccountsDrawerHeader(
decoration: BoxDecoration(
color: Colors.black45
),
accountName: Text('Raj'),
accountEmail: Text('abc123#gmail.com'),
currentAccountPicture: CircleAvatar(
backgroundColor: Colors.orange,
child:
Text('R', style:
TextStyle(fontSize: 40),),
),
),
ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
onTap: () {
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.contact_mail),
title: Text('Contact Us'),
onTap: () {
Navigator.pop(context);
},
),
],
),
),
///Body of the app
body: ListView.builder(
itemCount: productdata.length,
itemBuilder: (BuildContext context, int index) {
return
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: ListTile(
tileColor: Colors.cyan,
leading: Icon(Icons.star),
trailing: IconButton(onPressed: () {
showDialog(context: context, builder: (context) =>
AlertDialog(
title: Text('Delte this?'),
content: Text('Are you sure?'),
actions: <Widget>[
TextButton(onPressed: () {
Navigator.pop(context);
}, child:
Text('Cancel')),
TextButton(onPressed: () {
setState(() {
productdata.remove(productdata[index]);
Navigator.pop(context);
});
}, child:
const Text('Delete', style:
TextStyle(
color: Colors.black87,
fontSize: 16,
),))
],
));
}, icon: Icon(Icons.delete)),
title: Text(productdata[index].product!,
style:
TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
),),
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => Info(value: productdata[index])));
},
)),
],
);
}),
);
}
}
i tried using shared preferences but i am not geting any value.
here my info page where i want to get values:
import 'package:flutter/material.dart';
import 'package:list_ex/home.dart';
import 'package:list_ex/product.dart';
import 'package:list_ex/shared_pref.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Info extends StatelessWidget {
final Data value;
var pro;
var pri;
#override
void initState() {
getprodata();
getpridata();
}
Info({Key? key, required this.value}) : super(key: key);
#override
Widget build(BuildContext context) {
var pridata;
var prodata;
return Scaffold(
appBar: AppBar(
title: Text('Product Info'),
centerTitle: true,
backgroundColor: Colors.grey[800],
),
body: Center(
child: Card(
color: Colors.cyan,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
// ignore: prefer_interpolation_to_compose_strings
title: Text('Product Name:' + value.product!, style:
TextStyle(
fontSize: 20,
),),
subtitle: Text('Price:' + value.prize!, style:
TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold
),),
),
],
),
),
)
);
}
}
first import shared_preferences library into your project.
make instance of preference.
final prefs = await SharedPreferences.getInstance();
now write or store data into preference
counter is for Key and 10 is value
await prefs.setInt('counter', 10);
what ever key you will give here it will store data into that key only through this key you can get you data.
you can store any type of data like for int type you have to use setInt for String type use setString() and so on..
now you can get this data through get
final int? counter = prefs.getInt('counter');
in getInt() just pass key that you want to get data.
and use only one instance in every screen of you project to write and get data.
for more information see https://pub.dev/packages/shared_preferences

Show drawer over bottom navigation bar in Flutter

I have a drawer in a appbar and need to show it over the bottom navigation bar but can't put both in the same view, I don't know exactly how to do this.
This is what it looks like now and this is what it needs to look like.
This is part of the code of the view where the appbar is
class ContactsPage extends StatefulWidget {
final String title;
final String token;
final String qr;
String code;
final String name;
ContactsPage({this.name, this.token, this.qr, this.code, Key key, this.title})
: super(key: key);
#override
_ContactsPageState createState() => _ContactsPageState();
}
class _ContactsPageState extends State<ContactsPage> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
List<Contact> contactList;
bool showHorizontalBar = false;
bool ready = false;
#override
void initState() {
super.initState();
var userService = new UserService();
userService.getContacts(widget.token).then((value) => {
print(value),
if (value == '0')
{
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => LoginPage()))
}
else if (value == '3')
{
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => LoginPage()))
}
else
{
setState(() {
contactList = value;
ready = true;
})
},
print(contactList),
});
}
void showMessage(String message, [MaterialColor color = Colors.red]) {
_scaffoldKey.currentState..removeCurrentSnackBar();
_scaffoldKey.currentState.showSnackBar(
new SnackBar(backgroundColor: color, content: new Text(message)));
}
_navigateAndDisplaySelection(BuildContext context) async {
final result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Scanner(
qr: widget.qr,
token: widget.token,
)),
);
if (result != null) {
showMessage('$result', Colors.red);
}
}
Widget _addPerson() {
return FloatingActionButton(
onPressed: () {
_navigateAndDisplaySelection(context);
},
child: Icon(Icons.group_add),
backgroundColor: Color(0xff83bb37),
);
}
Widget buildMenuIcon() {
return IconButton(
icon: Icon(showHorizontalBar ? Icons.close : Icons.more_horiz),
onPressed: () {
setState(() {
showHorizontalBar = !showHorizontalBar;
});
},
);
}
Widget _simplePopup() => PopupMenuButton<int>(
itemBuilder: (context) => [
PopupMenuItem(
child: Row(
children: <Widget>[
IconButton(
icon: Icon(
Icons.delete,
color: Color(0xff83bb37),
),
onPressed: () => {},
),
IconButton(
icon: Icon(
Icons.favorite,
color: Color(0xff83bb37),
),
onPressed: () => {},
),
IconButton(
icon: Icon(
Icons.mail,
color: Color(0xff83bb37),
),
onPressed: () => {},
),
IconButton(
icon: Icon(
Icons.calendar_today,
color: Color(0xff83bb37),
),
onPressed: () => {},
),
IconButton(
icon: Icon(
Icons.call,
color: Color(0xff83bb37),
),
onPressed: () => {},
),
],
),
)
],
icon: Icon(
Icons.more_horiz,
size: 20,
color: Color(0xff4d4c48),
),
);
Widget _card(String first_name, String last_name, String email) {
return Card(
clipBehavior: Clip.antiAlias,
child: Column(
children: [
SizedBox(
height: 5.0,
),
ListTile(
leading: ClipRRect(
borderRadius: BorderRadius.circular(13.0),
child: Image.asset(
'assets/images/mujer.jpg',
width: 60.0,
height: 70.0,
fit: BoxFit.cover,
),
),
title: Row(
children: [
Text(
first_name,
style: TextStyle(
fontWeight: FontWeight.bold, color: Color(0xff4d4c48)),
),
SizedBox(width: 5.0),
Text(
last_name,
style: TextStyle(
fontWeight: FontWeight.bold, color: Color(0xff4d4c48)),
)
],
),
subtitle: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
email,
style: TextStyle(color: Color(0xff4d4c48)),
),
SizedBox(
height: 5.0,
),
Text(
'Prowebglobal',
style: TextStyle(
color: Color(0xff4d4c48), fontWeight: FontWeight.w600),
),
],
),
),
trailing: _simplePopup(),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ContactDetails(token: widget.token, email: email)));
},
),
SizedBox(
height: 20.0,
),
],
),
);
}
Widget textContainer(String string, Color color) {
return new Container(
child: new Text(
string,
style: TextStyle(
color: color, fontWeight: FontWeight.normal, fontSize: 16.0),
textAlign: TextAlign.start,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
margin: EdgeInsets.only(bottom: 10.0),
);
}
Widget _titulo() {
return new Container(
alignment: Alignment.topLeft,
padding: EdgeInsets.only(left: 20.0),
child: new Text(
'Contactos',
style: TextStyle(
color: Color(0xff83bb37),
fontWeight: FontWeight.bold,
fontSize: 25.0),
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
backgroundColor: Colors.white,
drawer: NavDrawer(
token: widget.token,
),
appBar: AppBar(
centerTitle: true,
backgroundColor: Color(0xfff0f0f0),
title: Image.asset(
'assets/images/logo-iso.png',
height: 50.0,
fit: BoxFit.contain,
alignment: Alignment.center,
),
iconTheme: new IconThemeData(color: Color(0xff707070)),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
onPressed: () {
},
),
]),
body: Column(children: [
SizedBox(
height: 20.0,
),
Expanded(
flex: 2,
child: _titulo(),
),
Expanded(
flex: 20,
child: Container(
child: ready
? ListView(
children: contactList
.map(
(Contact contact) => _card("${contact.first_name}",
"${contact.last_name}", "${contact.email}"),
)
.toList())
: Center(
child: Image.asset(
"assets/images/logo-gif.gif",
height: 125.0,
width: 125.0,
),
),
),
),
]),
floatingActionButton: _addPerson(),
);
}
}
And this is where de bottom navigation menu is
class HomePage extends StatefulWidget {
HomePage({
this.token,
this.code,
Key key,
}) : super(key: key);
final String token;
final String code;
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
String currentPage = 'contacts';
changePage(String pageName) {
setState(() {
currentPage = pageName;
});
}
#override
Widget build(BuildContext context) {
final Map<String, Widget> pageView = <String, Widget>{
"contacts": ContactsPage(
code: widget.code,
token: widget.token,
),
"profile": ProfilePage(
token: widget.token,
),
};
return Scaffold(
body: pageView[currentPage],
bottomNavigationBar: new BottomNavigationDot(
paddingBottomCircle: 21,
color: Colors.black.withOpacity(0.5),
backgroundColor: Colors.white,
activeColor: Colors.black,
items: [
new BottomNavigationDotItem(
icon: Icons.home,
onTap: () {
changePage("contacts");
}),
new BottomNavigationDotItem(icon: Icons.brush, onTap: () {}),
new BottomNavigationDotItem(icon: Icons.notifications, onTap: () {}),
new BottomNavigationDotItem(icon: Icons.favorite, onTap: () {}),
new BottomNavigationDotItem(
icon: Icons.person,
onTap: () {
changePage("profile");
}),
],
milliseconds: 400,
),
);
}
}
Edit:
I have thought on putting de appbar in the same level as de bottom navigation bar but I need to put different options on the appbar depending on the view so I thought on using diferent appbars, that's why I wanted it on the same level as the view.

Theme changing implicitly in Flutter

i'm trying to write a flutter application wHich takes two themes dark and brightness switch case device settings like this:
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Selectable GridView',
theme: ThemeData(
brightness: Brightness.dark,
),
home:HomePage(),
);
with the Brightness.light i have no problem but with the Brightness.dark it works correctly to some alert and when the app have an alert the alert color didn't change to dark and after the alert all the app change theme and color primaryColor:Colors.blue without any code written from me
import 'package:backback/Resultat/testclass.dart' as globals;
import 'package:flutter/cupertino.dart';
import 'package:hardware_buttons/hardware_buttons.dart' as HardwareButtons;
import 'dart:async';
import 'package:flutter/material.dart';
import 'ecouteurT.dart';
import 'flashT.dart';
class Boutontest extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<Boutontest> {
String _latestHardwareButtonEvent;
StreamSubscription<HardwareButtons.VolumeButtonEvent>
_volumeButtonSubscription;
StreamSubscription<HardwareButtons.HomeButtonEvent> _homeButtonSubscription;
StreamSubscription<HardwareButtons.LockButtonEvent> _lockButtonSubscription;
int a, b, c, d;
#override
void initState() {
super.initState();
new Future.delayed(Duration.zero, () {
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) => Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)), //this right here
child: Container(
height: 110,
child: Padding(
padding: EdgeInsets.all(0),
child: ListView(
children:
ListTile.divideTiles(context: context, tiles: [
ListTile(
title: Text(
'essayez de appyeez sur les boutons l\'un apres l\'autre et verifiez que tout bouton appyez ets montrez',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
onTap: null,
),
ListTile(
title: Text(
'OK',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.deepOrange),
),
onTap: () {
Navigator.of(context).pop(false);
},
)
]).toList())))));
});
_volumeButtonSubscription =
HardwareButtons.volumeButtonEvents.listen((event) {
setState(() {
_latestHardwareButtonEvent = event.toString();
});
if (_latestHardwareButtonEvent == 'VolumeButtonEvent.VOLUME_DOWN') {
b = 0;
}
if (_latestHardwareButtonEvent == 'VolumeButtonEvent.VOLUME_UP') {
c = 0;
}
});
_homeButtonSubscription = HardwareButtons.homeButtonEvents.listen((event) {
setState(() {
a = 0;
_latestHardwareButtonEvent = 'HOME_BUTTON';
});
});
_lockButtonSubscription = HardwareButtons.lockButtonEvents.listen((event) {
setState(() {
d = 0;
_latestHardwareButtonEvent = 'LOCK_BUTTON';
});
});
}
#override
void dispose() {
super.dispose();
_volumeButtonSubscription?.cancel();
_homeButtonSubscription?.cancel();
_lockButtonSubscription?.cancel();
}
#override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
return Scaffold(
appBar: AppBar(
title: const Text(
'Hi',
style: TextStyle(color: Colors.black),
),
),
body: Container(
child: Column(children: <Widget>[
Container(
height: height * 0.01,
),
Card(
child: ListTile(
leading: CircularProgressIndicator(
valueColor:
new AlwaysStoppedAnimation<Color>(Colors.deepOrange)),
title: Text(
'Detection des Boutons...',
style: TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Text('Element 1/1'),
trailing: InkWell(
onTap: () {
globals.Data.etatbouton('ignore');
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Flash()),
);
},
child: Text(
'Ignore>',
style: TextStyle(color: Colors.deepOrange),
),
),
)),
Container(
height: height * 0.02,
),
if (_latestHardwareButtonEvent == 'HOME_BUTTON' || a == 0)
Card(
child: ListTile(
title: Text('Le Bouton Home'),
trailing: Icon(
Icons.check,
color: Colors.deepOrange,
),
),
),
if (_latestHardwareButtonEvent == 'LOCK_BUTTON' || d == 0)
Card(
child: ListTile(
title: Text('Le Bouton Home'),
trailing: Icon(
Icons.check,
color: Colors.deepOrange,
),
),
),
if (_latestHardwareButtonEvent == 'VolumeButtonEvent.VOLUME_DOWN' ||
b == 0)
Card(
child: ListTile(
title: Text('Le Volume Down'),
trailing: Icon(
Icons.check,
color: Colors.deepOrange,
),
),
),
if (_latestHardwareButtonEvent == 'VolumeButtonEvent.VOLUME_UP' ||
c == 0)
Card(
child: ListTile(
title: Text('Le Volume Up'),
trailing: Icon(
Icons.check,
color: Colors.deepOrange,
),
),
),
Container(
margin: const EdgeInsets.all(15.0),
padding: const EdgeInsets.all(3.0),
decoration: BoxDecoration(
border: Border.all(
width: 3.0,
color: Colors.deepOrange,
),
borderRadius: BorderRadius.all(Radius.circular(
30.0) // <--- border radius here
),
),
child: FlatButton(
child: Text(
'Passer au test suivant',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
onPressed: () {
Future.delayed(Duration.zero, () {
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) =>
Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
20.0)), //this right here
child: Container(
height: 180,
child: Padding(
padding: EdgeInsets.all(0),
child: ListView(
children: ListTile.divideTiles(
context: context,
tiles: [
ListTile(
title: Text(
'Tout les boutons appyez sont montrez',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
onTap: null,
),
ListTile(
title: Text(
'Oui',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.deepOrange),
),
onTap: () {
globals.Data.etatbouton('1');
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
Flash()),
);
},
),
ListTile(
title: Text(
'Non',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.deepOrange),
),
onTap: () {
globals.Data.etatbouton('0');
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
Flash()),
);
},
)
]).toList())))));
});
},
))
]),
),
);
}
}
That's the code of one of the alert I need some help.
import 'package:flutter/material.dart';
import 'package:lamp/lamp.dart';
import 'dart:async';
import 'package:backback/Resultat/testclass.dart' as globals;
import 'batterieT.dart';
class Flash extends StatefulWidget {
#override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<Flash> {
bool _hasFlash = false;
bool _isOn = false;
double _intensity = 1.0;
#override
initState() {
super.initState();
initPlatformState();
}
initPlatformState() async {
bool hasFlash = await Lamp.hasLamp;
print("Device has flash ? $hasFlash");
setState(() { _hasFlash = hasFlash; });
}
#override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
return Scaffold(
appBar: AppBar(
title: Text('hi'),
),
body: Container(
//
child: Column(
children: <Widget>[
Container(
height: height*0.01,
),
Card(child:ListTile(
leading: CircularProgressIndicator(valueColor:
new AlwaysStoppedAnimation<Color>(Colors.deepOrange)),
title: Text('Detection Connexion et deconnexion des ecouteurs...',style:TextStyle(fontWeight: FontWeight.bold,color: Colors.deepOrange),),
subtitle: Text('Element 1/1'),
trailing: InkWell(
onTap: (){
globals.Data.etatkit('ignore');
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Batterie()),
);
},
child: Text('Ignore>',style: TextStyle(color: Colors.deepOrange),),
),
)),
Container(
height: height*0.02,
),
Container(
margin: const EdgeInsets.only(left: 20.0, right: 20.0),
child:Text(
'Veuillez branchez les ecouteurs plusieurs fois tout en verifiant si le texte afffiche correspond a l\'etat reel',
textAlign: TextAlign.center,)),
if(_isOn==false)
new InkWell(child: Image.asset('assets/flash.jpg'),
onTap:(){_turnFlash();} ,) ,
if(_isOn==true)
new InkWell(child: Image.asset('assets/flashO.jpg'),
onTap:(){_turnFlash();} ,),
Divider(),
Container(
margin: const EdgeInsets.only(left: 20.0, right: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
InkWell (child:Text('Ne correspond pas',style: TextStyle(color: Colors.deepOrange),)
, onTap: (){
globals.Data.etatkit('0');
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Batterie()),
);
},),
InkWell(child: Text('Correspond',style: TextStyle(color: Colors.deepOrange),),
onTap: (){
globals.Data.etatkit('1');
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Batterie()),
);
},)
],
),
)
],
),
),
);
}
Future _turnFlash() async {
_isOn ? Lamp.turnOff() : Lamp.turnOn(intensity: _intensity);
var f = await Lamp.hasLamp;
setState((){
_hasFlash = f;
_isOn = !_isOn;
});
}
_intensityChanged(double intensity) {
Lamp.turnOn(intensity : intensity);
setState((){
_intensity = intensity;
});
}
}
and in this class when the navigator pass to this class I lost dark theme.

Flutter: How can I keep to my selected navigator when I'll go to a new screen and go back

I'm having a problem right now in my bottom navigation in flutter.
I have four navigation "Community, Feeds, Activity, Profile".
In my "Feeds" navigation I have a button named "View Profile" everytime I click that button it directs me to a new screen using
"Navigator.push(context, MaterialPageRoute())"
and I notice it auto generates a "<-" or "back arrow" icon on the appbar.
The problem is everytime I click that "back arrow", it redirects me to the first option on my navigation bar.
Not on the "Feeds" navigation.
Any tips how to fix this?
Here is my bottom navigation code:
_getPage(int page) {
switch (page) {
case 0:
return NewsFeed();
case 1:
return OrgAndNews();
case 2:
return MyActivity();
case 3:
return Profile();
}
}
int currentPage = 0;
void _onBottomNavBarTab(int index) {
setState(() {
currentPage = index;
});
}
return Scaffold(
body: Container(
child: _getPage(currentPage),
),
bottomNavigationBar: Container(
height: _height * .09,
child: BottomNavigationBar(
backgroundColor: Color(0xFFFFFFFF),
fixedColor: Color(0xFF121A21),
unselectedItemColor: Color(0xFF121A21),
currentIndex: currentPage,
onTap: _onBottomNavBarTab,
items: [
BottomNavigationBarItem(
icon: Icon(FontAwesomeIcons.users),
title: Padding(
padding: const EdgeInsets.only(top: 3.0),
child: Text('Community', style: TextStyle(fontSize: ScreenUtil.getInstance().setSp(35),
fontWeight: FontWeight.w800),
),
),
),
BottomNavigationBarItem(
icon: Icon(FontAwesomeIcons.newspaper),
title: Padding(
padding: const EdgeInsets.only(top: 3.0),
child: Center(
child: Text('Feeds', style: TextStyle(fontSize: ScreenUtil.getInstance().setSp(35),
fontWeight: FontWeight.w800),),
),
),
),
BottomNavigationBarItem(
icon: Icon(FontAwesomeIcons.listUl),
title: Padding(
padding: const EdgeInsets.only(top: 3.0),
child: Text('My Activity', style: TextStyle(fontSize: ScreenUtil.getInstance().setSp(35),
fontWeight: FontWeight.w800),),
),
),
BottomNavigationBarItem(
icon: Icon(FontAwesomeIcons.userAlt),
title: Padding(
padding: const EdgeInsets.only(top: 3.0),
child: Text('Profile', style: TextStyle(fontSize: ScreenUtil.getInstance().setSp(35),
fontWeight: FontWeight.w800),),
),
),
],
),
),
);
My code for the page when you click the "View Profile":
class OrgProfile extends StatefulWidget {
OrgProfile(this.orgName) : super();
final String orgName;
#override
_OrgProfileState createState() => _OrgProfileState();
}
class _OrgProfileState extends State<OrgProfile> {
#override
final db = Firestore.instance;
Container buildItem(DocumentSnapshot doc) {
return Container(
child: Column(
children: <Widget>[
Center(
child: Padding(
padding: const EdgeInsets.only(top: 20.0),
child: CircleAvatar(
radius: 70,
),
),
),
Text(
'${doc.data['Email']}',
style: TextStyle(color: Colors.black),
)
],
),
);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.orgName),
),
body: StreamBuilder<QuerySnapshot>(
stream: db
.collection('USERS')
.where('Name of Organization', isEqualTo: widget.orgName)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Column(
children: snapshot.data.documents
.map((doc) => buildItem(doc))
.toList());
} else {
return SizedBox();
}
}),
);
}
}
My code when i click the "View Profile" button:
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => new
OrgProfile(
doc.data['Name of Organization'])));
},
My feeds UI:
My View Profile UI:
Have you used MaterialPage Route With Builder Like This?
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => new MyToDoThunder(),
),
)
Homepage Code :-
class HomePage extends StatefulWidget {
#override
State<StatefulWidget> createState() {
//
return new HomePageState();
}
}
class HomePageState extends State<HomePage> {
var db = DatabaseHelper();
int _selectedIndex = 0;
List<bool> textColorChange = [true, false, false, false];
final _widgetOptions = [
StatusPageRedux(),
RequestPage(),
NotificationPage(),
DashboardPage(),
];
_bottomNavigationView() {
return new Theme(
isMaterialAppTheme: true,
data: Theme.of(context)
.copyWith(canvasColor: Theme.of(context).primaryColor),
child: new BottomNavigationBar(
type: BottomNavigationBarType.fixed,
onTap: _onItemTapped,
currentIndex: _selectedIndex,
fixedColor: Colors.white,
items: [
new BottomNavigationBarItem(
activeIcon: ThunderSvgIcons(
path: 'assets/icons/Status.svg', height: 20.0, color: Colors.white),
icon: ThunderSvgIcons(
path: 'assets/icons/Status.svg', height: 20.0, color: Colors.white30),
title: new Text(
'Status',
style: TextStyle(
color: textColorChange[0] ? Colors.white : Colors.white30),
),
),
new BottomNavigationBarItem(
title: new Text(
'Requests',
style: TextStyle(
color: textColorChange[1] ? Colors.white : Colors.white30),
),
activeIcon: ThunderSvgIcons(
path: 'assets/icons/Requests.svg', height: 20.0, color: Colors.white),
icon: ThunderSvgIcons(
path: 'assets/icons/Requests.svg',
height: 20.0,
color: Colors.white30),
),
new BottomNavigationBarItem(
activeIcon: ThunderSvgIcons(
path: 'assets/icons/Notifications.svg',
height: 20.0,
color: Colors.white),
icon: ThunderSvgIcons(
path: 'assets/icons/Notifications.svg',
height: 20.0,
color: Colors.white30),
title: new Text(
'Notifications',
style: TextStyle(
color: textColorChange[2] ? Colors.white : Colors.white30),
),
),
new BottomNavigationBarItem(
activeIcon: ThunderSvgIcons(
path: 'assets/icons/dashboard.svg',
height: 20.0,
color: Colors.white),
icon: ThunderSvgIcons(
path: 'assets/icons/dashboard.svg',
height: 20.0,
color: Colors.white30),
title: new Text(
'Dashboard',
style: TextStyle(
color: textColorChange[3] ? Colors.white : Colors.white30),
),
),
],
),
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new Center(child: _widgetOptions.elementAt(_selectedIndex)),
bottomNavigationBar: _bottomNavigationView(),
);
}
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
for (int i = 0; i < textColorChange.length; i++) {
if (index == i) {
textColorChange[i] = true;
} else {
textColorChange[i] = false;
}
}
});
}
}
You will have to add your way back to the stack.
Try the below appbar in you 'tuloung duloung' title page, it should do the trick.
Note if your homescreen has tabs its advised to pass the index of the page you want to reach on exiting 'tuloung duloung'.
Let me know if it helps.
AppBar(
backgroundColor: Colors.transparent,
centerTitle: false,
brightness: Brightness.dark,
title: Container(
width: 150,
child: Row(
children:[
IconButton(icon:Icons.back_arrow,
onpressed:() =>
Navigator.pushReplacementNamed(context, '/Your Home_Screen');
),
Text('tuloung duloung',
style: TextStyle(
fontWeight: FontWeight.w400,
color: theme.primaryColor,
)),
]
),
),
automaticallyImplyLeading: false,
iconTheme: IconThemeData(
color: theme.primaryColor,
),
actions:[ Container(
width: 150,
child: FlatButton.icon(
label: Text('Done'),
icon: Icon(Icons.check_circle),
onPressed: () => {
setState(() {
takingsnap = true;
_captureImage();
})
}),
),
]
),