Could not find the correct Provider<CartItemCounter> above this HomeScreen Widget - flutter

I keep on getting this problem:
Unhandled Exception: Error: Could not find the correct Provider above this HomeScreen Widget
Since I am trying to implement Cart Item Counter, there is this bug.
Here is my code:
Main.dart
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
sharedPreferences = await SharedPreferences.getInstance();
await Firebase.initializeApp();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (c) => CartItemCounter()),
ChangeNotifierProvider(create: (c) => TotalAmount()),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Users App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MySplashScreen(),
),
);
}
}
Below is my App Bar, This is where i send users to Cart:
class MyAppBar extends StatefulWidget with PreferredSizeWidget {
final PreferredSizeWidget? bottom;
final String? sellerUID;
MyAppBar({this.bottom, this.sellerUID});
#override
_MyAppBarState createState() => _MyAppBarState();
#override
Size get preferredSize => bottom == null
? Size(56, AppBar().preferredSize.height)
: Size(56, 80 + AppBar().preferredSize.height);
}
class _MyAppBarState extends State<MyAppBar> {
#override
Widget build(BuildContext context) {
return AppBar(
flexibleSpace: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.cyan,
Colors.amber,
],
begin: FractionalOffset(0.0, 0.0),
end: FractionalOffset(1.0, 0.0),
stops: [0.0, 1.0],
tileMode: TileMode.clamp,
)),
),
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context);
},
),
title: const Text(
"iFood",
style: TextStyle(fontSize: 45, fontFamily: "Signatra"),
),
centerTitle: true,
automaticallyImplyLeading: true,
actions: [
Stack(
children: [
IconButton(
icon: const Icon(
Icons.shopping_cart,
color: Colors.cyan,
),
onPressed: () {
//send user to cart screen
Navigator.push(
context,
MaterialPageRoute(
builder: (c) =>
CartScreen(sellerUID: widget.sellerUID)));
},
),
Positioned(
child: Stack(
children: [
const Icon(
Icons.brightness_1,
size: 20.0,
color: Colors.green,
),
Positioned(
top: 3,
right: 4,
child: Center(
child: Consumer<CartItemCounter>(
builder: (context, counter, c) {
return Text(
counter.count.toString(),
style: const TextStyle(
color: Colors.white, fontSize: 12),
);
},
),
),
),
],
),
),
],
),
],
);
}
}
Following is My Cart Screen:
I want to display cart items with quantity number
class CartScreen extends StatefulWidget {
final String? sellerUID;
CartScreen({this.sellerUID});
#override
_CartScreenState createState() => _CartScreenState();
}
class _CartScreenState extends State<CartScreen> {
List<int>? separateItemQuantityList;
num totalAmount = 0;
#override
void initState() {
super.initState();
totalAmount = 0;
Provider.of<TotalAmount>(context, listen: false).displayTotalAmount(0);
separateItemQuantityList = separateItemQuantities();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
flexibleSpace: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.cyan,
Colors.amber,
],
begin: FractionalOffset(0.0, 0.0),
end: FractionalOffset(1.0, 0.0),
stops: [0.0, 1.0],
tileMode: TileMode.clamp,
)),
),
leading: IconButton(
icon: const Icon(Icons.clear_all),
onPressed: () {
clearCartNow(context);
},
),
title: const Text(
"iFood",
style: TextStyle(fontSize: 45, fontFamily: "Signatra"),
),
centerTitle: true,
automaticallyImplyLeading: true,
actions: [
Stack(
children: [
IconButton(
icon: const Icon(
Icons.shopping_cart,
color: Colors.cyan,
),
onPressed: () {
print("clicked");
},
),
Positioned(
child: Stack(
children: [
const Icon(
Icons.brightness_1,
size: 20.0,
color: Colors.green,
),
Positioned(
top: 3,
right: 4,
child: Center(
child: Consumer<CartItemCounter>(
builder: (context, counter, c) {
return Text(
counter.count.toString(),
style: const TextStyle(
color: Colors.white, fontSize: 12),
);
},
),
),
),
],
),
),
],
),
],
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
const SizedBox(
width: 10,
),
Align(
alignment: Alignment.bottomLeft,
child: FloatingActionButton.extended(
label: const Text(
"Clear Cart",
style: TextStyle(fontSize: 16),
),
backgroundColor: Colors.cyan,
icon: const Icon(Icons.clear_all),
onPressed: () {
clearCartNow(context);
Navigator.push(context,
MaterialPageRoute(builder: (c) => const MySplashScreen()));
Fluttertoast.showToast(msg: "Cart has been cleared.");
},
),
),
Align(
alignment: Alignment.bottomLeft,
child: FloatingActionButton.extended(
label: const Text(
"Check Out",
style: TextStyle(fontSize: 16),
),
backgroundColor: Colors.cyan,
icon: const Icon(Icons.navigate_next),
onPressed: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (c) => AddressScreen(
// totalAmount: totalAmount.toDouble(),
// sellerUID: widget.sellerUID,
// ),
// ),
// );
},
),
),
],
),
body: CustomScrollView(
slivers: [
//overall total amount
SliverPersistentHeader(
pinned: true, delegate: TextWidgetHeader(title: "My Cart List")),
SliverToBoxAdapter(
child: Consumer2<TotalAmount, CartItemCounter>(
builder: (context, amountProvider, cartProvider, c) {
return Padding(
padding: const EdgeInsets.all(8),
child: Center(
child: cartProvider.count == 0
? Container()
: Text(
"Total Price: " + amountProvider.tAmount.toString(),
style: const TextStyle(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.w500,
),
),
),
);
}),
),
//display cart items with quantity number
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection("items")
.where("itemID", whereIn: separateItemIDs())
.orderBy("publishedDate", descending: true)
.snapshots(),
builder: (context, snapshot) {
return !snapshot.hasData
? SliverToBoxAdapter(
child: Center(
child: circularProgress(),
),
)
: snapshot.data!.docs.length == 0
? //startBuildingCart()
Container()
: SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
Items model = Items.fromJson(
snapshot.data!.docs[index].data()!
as Map<String, dynamic>,
);
if (index == 0) {
totalAmount = 0;
totalAmount = totalAmount +
(model.price! *
separateItemQuantityList![index]);
} else {
totalAmount = totalAmount +
(model.price! *
separateItemQuantityList![index]);
}
if (snapshot.data!.docs.length - 1 == index) {
WidgetsBinding.instance
.addPostFrameCallback((timeStamp) {
Provider.of<TotalAmount>(context,
listen: false)
.displayTotalAmount(
totalAmount.toDouble());
});
}
return CartItemDesign(
model: model,
context: context,
quanNumber: separateItemQuantityList![index],
);
},
childCount: snapshot.hasData
? snapshot.data!.docs.length
: 0,
),
);
},
),
],
),
);
}
}

It's hard to tell what is the problem without looking at the whole source code.
My guess is that you need to pass the ChangeNotifierProvider instance across routes (basically whenever you do Navigator.push()).
Check out this answer.

When passing ChangeNotifierProvider in main
Pass it like this
ChangeNotifierProvider(
create : (context) => CartItemCounter(),
child : CartScreen (), // screen where you want to access the Provider
),

Related

RangeError (index): Invalid Value: Only valid value is 0: 1 error in MaterialApp

i'm pretty new to programming and currently facing an issue where one of my screens wont display. The screen is sort of like a shopping cart screen where it displays the items the user has chosen. I'm very lost because for some reason flutter tells me the error is located in MaterialApp in main.
Here is my main.dart
import 'package:eat_easy_project/assistantMethod/shopping_List_Counter.dart';
import 'package:eat_easy_project/global/global.dart';
import 'package:eat_easy_project/splashScreen/splash_screen.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:provider/provider.dart';
Future<void> main() async
{
WidgetsFlutterBinding.ensureInitialized();
sharedPreferences = await SharedPreferences.getInstance();
await Firebase.initializeApp();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (c)=> ShoppingListCounter()),
],
child: MaterialApp(
title: 'EatEasy Project',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MySplashScreen(),
),
);
}
}
and below is the cart screen where it the other code where it shoul've displayed
import 'package:eat_easy_project/models/ingredients.dart';
import 'package:flutter/material.dart';
class ShoppingListDesign extends StatefulWidget
{
final Ingredients? model;
BuildContext? context;
final List <int>? separateIngredientQuantitiesList;
ShoppingListDesign({
this.model,
this.context,
this.separateIngredientQuantitiesList,
});
#override
State<ShoppingListDesign> createState() => _ShoppingListDesignState();
}
class _ShoppingListDesignState extends State<ShoppingListDesign> {
#override
Widget build(BuildContext context) {
return InkWell(
splashColor: Colors.cyan,
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Container(
height: 165,
width: MediaQuery.of(context).size.width,
child: Row(
children: [
Image.network(widget.model!.ingredientAvatarUrl!, width: 140, height: 120,),
const SizedBox(width: 6,),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.model!.ingredientName!,
style: const TextStyle(
color: Colors.black,
fontSize: 16,
fontFamily: "Kiwi",
),
),
const SizedBox(
height: 1.0,
),
Row(
children: [
const Text(
"x ",
style: TextStyle(
color: Colors.black,
fontSize: 25,
fontFamily: "Acme",
),
),
Text(
widget.separateIngredientQuantitiesList.toString(),
style: const TextStyle(
color: Colors.black,
fontSize: 25,
fontFamily: "Acme",
),
),
],
),
Row(
children: [
const Text(
"Price: ",
style: TextStyle(
fontSize: 15,
color: Colors.grey,
),
),
const Text(
"RM ",
style: TextStyle(
fontSize: 15,
color: Colors.grey,
),
),
Text(
widget.model!.ingredientPrice.toString(),
style: const TextStyle(
fontSize: 15,
color: Colors.grey,
),
),
],
)
],
),
],
),
),
),
);
}
}
I'm following a guide from udemy to help me code and for some reason even though I copied the exact same code with minor adjustments, I still got this error. My database json is located in firebase.
Error in detail:
enter image description here
Error for assitantMethod led me to var quanNumber = int.parse(listIngredientCharacters1.toString());
separateIngredientUIDs()
{
List<String> separateIngredientUIDsList=[], defaultIngredientList=
[];
int i=0;
defaultIngredientList =
sharedPreferences!.getStringList("userShoppingList")!;
for(i; i<defaultIngredientList.length; i++)
{
String ingredient = defaultIngredientList[i].toString();
var pos = ingredient.lastIndexOf(":");
String getIngredientID = (pos != -1) ? ingredient.substring(0, pos)
: ingredient;
print("\nThis is ingredientID now = " + getIngredientID);
separateIngredientUIDsList.add(getIngredientID);
}
print("\nThis is Ingredients List now = " );
print(separateIngredientUIDsList);
return separateIngredientUIDsList;
}
addIngredientToCart(String? ingredientUID, BuildContext context, int
ingredientCounter)
{
List<String>? tempList =
sharedPreferences!.getStringList("userShoppingList");
tempList!.add(ingredientUID! + ":$ingredientCounter");
FirebaseFirestore.instance.collection("user")
.doc(firebaseAuth.currentUser!.uid).update({
"userShoppingList": tempList,
}).then((value)
{
Fluttertoast.showToast(msg: "Ingredient Added Successfully.");
sharedPreferences!.setStringList("userShoppingList", tempList);
//update badge
Provider.of<ShoppingListCounter>(context, listen:
false).displayShoppingListIngredientNumber();
});
}
separateIngredientQuantities()
{
List<int> separateIngredientQuantityList=[];
List<String> defaultIngredientList=[];
int i=0;
defaultIngredientList =
sharedPreferences!.getStringList("userShoppingList")!;
for(i; i<defaultIngredientList.length; i++)
{
String ingredient = defaultIngredientList[i].toString();
List<String> listIngredientCharacters =
ingredient.split(":").toList();
var quanNumber = int.parse(listIngredientCharacters[0].toString());
print("\nThis is Quantity Number = " + quanNumber.toString());
separateIngredientQuantityList.add(quanNumber);
}
print("\nThis is Quantity List now = " );
print(separateIngredientQuantityList);
return separateIngredientQuantityList;
}
Error for shoppinglistscreen led me to separateIngredientQuantities();
class ShoppingListScreen extends StatefulWidget {
Ingredients? model;
ShoppingListScreen({this.model});
#override
State<ShoppingListScreen> createState() => _ShoppingListScreenState();
}
class _ShoppingListScreenState extends State<ShoppingListScreen>
{
#override
void initState() {
super.initState();
separateIngredientQuantities();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar
(
flexibleSpace: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
Color.fromARGB(255, 192, 234, 240),
Color.fromARGB(255, 108, 173, 70),
],
begin: FractionalOffset(0.0, 0.0),
end: FractionalOffset(1.0, 0.0),
stops: [0.0, 1.0],
tileMode: TileMode.clamp,
)
),
),
title: const Text(
"EatEasy",
style: TextStyle(color: Colors.white, fontWeight:
FontWeight.bold,)
),
centerTitle: true,
automaticallyImplyLeading: true,
actions: [
Stack(
children: [
IconButton(
icon: const Icon(Icons.shopping_cart, color: Colors.cyan,),
onPressed: ()
{
Navigator.push(context, MaterialPageRoute(builder: (c)=>
ShoppingListScreen(model: widget.model,)));
},
),
Positioned(
child: Stack(
children: [
const Icon(
Icons.brightness_1,
size: 20.0,
color: Color.fromARGB(255, 29, 88, 31),
),
Positioned(
top: 3,
right: 4,
child: Center(
child: Consumer<ShoppingListCounter>(
builder: (context, counter, c)
{
return Text(
counter.count.toString(),
style: const TextStyle(color: Color.fromARGB(255, 209, 218, 226)),
);
}
),
),
),
],
),
),
],
),
],
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
SizedBox(width: 10,),
Align(
alignment: Alignment.bottomLeft,
child: FloatingActionButton.extended(
label: const Text("Clear List", style: TextStyle(fontSize: 16),),
backgroundColor: Colors.cyan,
icon: const Icon(Icons.clear_all),
onPressed: ()
{
},
),
),
Align(
alignment: Alignment.bottomLeft,
child: FloatingActionButton.extended(
label: const Text("Calculate Total", style: TextStyle(fontSize: 16),),
backgroundColor: Colors.cyan,
icon: const Icon(Icons.calculate),
onPressed: ()
{
},
),
)
],
),
body: CustomScrollView(
slivers: [
//overall total amount
SliverPersistentHeader(
pinned: true,
delegate: TextWidgetHeader(title: "Total Amount = 120"),
),
//display cart ingredients with quantity
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection("ingredients")
.where("ingredientUID", whereIn: separateIngredientUIDs())
.orderBy("ingredientPrice", descending: true)
.snapshots(),
builder: (context, snapshot)
{
return !snapshot.hasData
? SliverToBoxAdapter(child: Center(child:
circularProgress()),)
: snapshot.data!.docs.length == 0
? //startBuildingList
Container()
: SliverList(
delegate: SliverChildBuilderDelegate((context, index)
{
Ingredients model = Ingredients.fromJson(
snapshot.data!.docs[index].data()! as Map<String,
dynamic>,
);
return ShoppingListDesign(
model: model,
context: context,
separateIngredientQuantitiesList: [index] ,
);
},
//childCount: snapshot.hasData ?
snapshot.data!.docs.length : 0,
),
);
},
),
],
),
);
}
}

The class 'SimpleFoldingCell' doesn't have a default constructor

https://github.com/flutter-devs/flutter_folding_cell_demo/blob/master/lib/demo_screen.dart
I'm trying to follow the code in the link above.
But in the SimpleFoldingCell part, an error named 'The class 'SimpleFoldingCell' doesn't have a default constructor.' occurs.
Could
Is there a way to resolve this error in Dart?
class Notific extends StatefulWidget{
#override
_State createState() => _State();
}
class _State extends State<Notific>{
late List<TechnologyModel> _technologyList;
#override
void initState() {
super.initState();
_technologyList = [
TechnologyModel(title: "Application Development",),
TechnologyModel(title: "Research & Development",),
TechnologyModel(title: "Big Data & Analytics",),
TechnologyModel(title: "Support Services",),
TechnologyModel(title: "QA & Software Testing",),
];
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.pink[200],
title: Text("Folding Cell Demo",
style: TextStyle(color: Colors.white),),
),
body: Container(
child: ListView.builder(
itemCount: _technologyList.length,
itemBuilder: (context, index) {
return SimpleFoldingCell(
frontWidget: _buildFrontWidget(index),
innerTopWidget: _buildInnerWidget(index),
innerBottomWidget: _buildInnerBottomWidget(),
cellSize: Size(MediaQuery.of(context).size.width, 125),
padding: EdgeInsets.all(15),
animationDuration: Duration(milliseconds: 200),
borderRadius: 10,
onOpen: () => print('$index cell opened'),
onClose: () => print('$index cell closed'),
);
},
),
),
);
}
Widget _buildFrontWidget(int index) {
return Builder(
builder: (BuildContext context) {
return Container(
color: Colors.cyan[100],
alignment: Alignment.bottomCenter,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Aeologic Technology",
style: TextStyle(
fontSize:20.0,
color: Colors.black,
),
),
SizedBox(height: 10,),
FlatButton(
onPressed: () {
final foldingCellState = context
.findAncestorStateOfType<SimpleFoldingCellState>();
foldingCellState?.toggleFold();
},
child: Text(
"OPEN",
),
textColor: Colors.white,
color: Colors.indigoAccent[100],
splashColor: Colors.white.withOpacity(0.5),
),
],
),
);
},
);
}
Widget _buildInnerBottomWidget() {
return Builder(
builder: (context) {
return Container(
color: Colors.blueGrey[50],
alignment: Alignment.bottomCenter,
child: Padding(
padding: EdgeInsets.only(bottom: 10),
child: FlatButton(
onPressed: () {
final foldingCellState = context
.findAncestorStateOfType<SimpleFoldingCellState>();
foldingCellState?.toggleFold();
},
child: Text(
"Close",
),
textColor: Colors.white,
color: Colors.redAccent[100],
splashColor: Colors.white.withOpacity(0.5),
),
),
);
}
);
}
Widget _buildInnerWidget(int index) {
return Builder(
builder: (context) {
return Container(
color: Colors.pink[100],
padding: EdgeInsets.only(top: 10),
child: Align(
alignment: Alignment.center,
child: Text(
_technologyList[index].title,
style: TextStyle(
fontSize:20.0,
color: Colors.black,
),
),
),
);
},
);
}
}
class TechnologyModel {
String title;
TechnologyModel({
required this.title,
});
}
For some reason they've created only a named constructor.
return SimpleFoldingCell.create(
frontWidget: _buildFrontWidget(index),
innerWidget: _buildInnerWidget(index),
// innerTopWidget: _buildInnerWidget(index),
// innerBottomWidget: _buildInnerBottomWidget(),
cellSize: Size(MediaQuery.of(context).size.width, 125),
padding: EdgeInsets.all(15),
animationDuration: Duration(milliseconds: 200),
borderRadius: 10,
onOpen: () => print('$index cell opened'),
onClose: () => print('$index cell closed'),
);
It looks like the demo you're looking at is a bit outdated, since some of those properties don't exist anymore (see commented code).

How to keep disappearing Flutter Bottom Navigation and AppBar after navigating from subpages

I have a bottom Tab bar in my app for navigation and appbar, from the menu page after adding products in Cart screen there is Continue button when i pressed it take me to Login screen, there a normal login with and otp verification, now when i try to navigate back to menu screen after successfull otp verification, i see Tab bar disappeared and the App bar.
How i can fix this problem
Cart Screen
return Scaffold
....
row
...
Container showOrderConfirmationBtn(BuildContext context) {
return Container(
height: 50.0,
decoration: BoxDecoration(
border: Border.all(
color: Colors.transparent, style: BorderStyle.solid, width: 1.0),
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(10.0),
),
child: FlatButton(
onPressed: () {
isLoggedIn == false
? Navigator.push(
context, MaterialPageRoute(builder: (context) => LoginPage()))
: Navigator.of(context).push(MaterialPageRoute(
builder: (context) => CarConfirmationCompletePage()));
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Center(
child: Wrap(
crossAxisAlignment: WrapCrossAlignment.center,
children: [
Text(
'Continue',
style: TextStyle(
color: Colors.white,
fontFamily: 'BuffetRegular',
fontSize: 13,
letterSpacing: 0.5),
),
],
),
)
],
),
),
);
}
}
Login Screen
return Scafold
....
GestureDetector(
onTap: () async {
final prefs =
await SharedPreferences.getInstance();
final customerData = LoginModel(
mobile: maskFormatter.getUnmaskedText());
final result = await loginServices
.loginCustomer(customerData);
final customerId = result['id'];
if (result['existsFlag'] == '1') {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => OtpVerification(
customerId: customerId)));
} else {
// Registering customer
// Registering customer device info
// and navigating the user to otpverification page
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => OtpVerification(
customerId: customerId)));
}
},
child: Container(
margin: const EdgeInsets.only(right: 20.0),
width: 40,
height: 40.0,
decoration: BoxDecoration(
color: Colors.green.shade300,
borderRadius: BorderRadius.circular(10.0),
),
child: Icon(Icons.arrow_forward_ios),
),
),
Otp Screen
return Scaffold
....
PinEntryTextField(
fieldWidth: 60.0,
showFieldAsBox: true,
onSubmit: (String pin) async {
final prefs = await SharedPreferences.getInstance();
// redirected to menu page
final optData =
OtpModel(customerId: widget.customerId, otp: pin);
final result = await loginServices.otpVerify(optData);
if (result['existsFlag'] == '1') {
// setting customer prefs
prefs.setBool('isLoggedIn', true);
Navigator.push(context,
MaterialPageRoute(builder: (context) => MenuPage()));
} else {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: null,
content: Text('неверный код подтверждения '),
);
},
); //end showDialog()
}
// ...............................
// showDialog(
// context: context,
// builder: (context) {
// return AlertDialog(
// title: Text("Pin"),
// content: Text('Pin entered is $pin'),
// );
// },
// ); //end showDialog()
// ...............................
}, // end onSubmit
),
Menu Page
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:get_it/get_it.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
// ... Constants
import '../constants.dart';
// ... Providers
import '../providers/order_notify.dart';
// ... Models
import '../models/cart_order.dart';
import '../models/menu_model.dart';
// ... API'S
import '../apis/api_response.dart';
import '../apis/menu-api.dart';
// ... Pages
import '../pages/menu_detail.dart';
class MenuPage extends StatefulWidget {
final Products pro;
MenuPage({Key key, this.pro}) : super(key: key);
#override
_MenuPageState createState() => _MenuPageState();
}
class _MenuPageState extends State<MenuPage> {
ProductApi get productsServices => GetIt.I<ProductApi>();
APIResponse<List<Products>> _apiResponse;
bool _isLoading = false;
void _fetchProducts() async {
setState(() {
_isLoading = true;
});
_apiResponse = await productsServices.getProductsList();
setState(() {
_isLoading = false;
});
}
hasDiscount(product) {
return product.hasDiscount == '1'
? product.priceAfter
: product.hasDiscount == '0'
? product.priceBefore
: product.priceAfter;
}
#override
void initState() {
_fetchProducts();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: ListView(
physics: PageScrollPhysics(),
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: kDefaultPadding, vertical: kDefaultPadding),
child: Text('Меню', style: kStyleHeaders),
),
SizedBox(
height: 10.0,
),
Builder(builder: (_) {
if (_isLoading) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 200.0),
child: Center(child: null),
);
}
if (_apiResponse.error) {
return Center(child: Text(_apiResponse.errorMessage));
}
if (_apiResponse.data.length == 0) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 200.0),
child: Center(
child: Text(
'No products has been found..!',
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
fontFamily: 'BuffetBold',
color: Colors.black,
),
),
),
);
}
return GridView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemCount: _apiResponse.data.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 0.72,
mainAxisSpacing: 1.0,
crossAxisSpacing: 1.0,
),
itemBuilder: (context, index) {
var product = _apiResponse.data[index];
return CachedNetworkImage(
imageUrl: product.imageMedium,
imageBuilder: (context, imageProvider) => Column(
children: [
GestureDetector(
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProductDetail(
id: product.id,
title: product.title,
description: product.description,
structure: product.structure,
imageLarge: product.imageLarge,
weight: product.weight,
hasDiscount: product.hasDiscount,
priceBefore:
double.parse(product.priceBefore),
priceAfter:
double.parse(product.priceAfter),
isHit: product.isHit,
isNew: product.isNew,
isSpicy: product.isSpicy,
isRecommended: product.isRecommended,
isVegetarian: product.isVegetarian,
attributes: product.attributes),
),
),
child: Container(
alignment: Alignment(-1, 0.9),
child: (product.isNew == '1')
? Image.asset(
'assets/images/new.png',
width: 60.0,
)
: null,
height: 165.0,
width: 165.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
),
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 2.0,
spreadRadius: 0,
offset: Offset(0, 2))
],
),
),
),
Padding(
padding: EdgeInsets.symmetric(
vertical: 10.0, horizontal: 10.0),
child: Row(
children: [
Flexible(
child: Text(product.title,
style: kStyleTitle))
],
),
),
Container(
margin: EdgeInsets.symmetric(horizontal: 10.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
product.weight != null
? product.weight
: '',
style: kStyleWeight),
Text(
product.hasDiscount != '0'
? product.priceBefore
: '',
style: kStyleDiscount),
Container(
margin: EdgeInsets.symmetric(
horizontal: 3, vertical: 0),
height: 30.0,
width: 70.0,
child: FlatButton(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(20.0),
),
color: kPrimaryColor,
textColor: Colors.white,
padding:
EdgeInsets.symmetric(horizontal: 5.0),
onPressed: () {
// ... Todo
context.read<OrderNotify>().addOrder(
CartOrder(
product: product,
qty: 1,
price: hasDiscount(product)),
);
},
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text(hasDiscount(product),
style: kStylePrice),
Icon(
FontAwesomeIcons.rubleSign,
size: 13.0,
color: Colors.white,
)
],
),
),
),
],
),
),
],
),
placeholder: (context, url) => Center(
child: CircularProgressIndicator(
valueColor:
AlwaysStoppedAnimation(Color(0xffB81F33)),
),
),
errorWidget: (context, url, error) => Icon(
Icons.error,
size: 40.0,
color: Theme.of(context).primaryColor,
),
);
},
);
}),
],
),
],
),
),
);
}
}
Main.dart
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:get_it/get_it.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
// ... API'S
import './apis/category-api.dart';
import './apis/menu-api.dart';
import './apis/promotion-api.dart';
import './apis/login-api.dart';
import './apis/ipaddress-api.dart';
import './apis/deviceinfo-api.dart';
import './apis/customer_deviceinfo-api.dart';
// Providers
import './providers/order_notify.dart';
import 'app.dart';
void setupLocator() {
GetIt.I.registerLazySingleton(() => PromotionApi());
GetIt.I.registerLazySingleton(() => CategoriesApi());
GetIt.I.registerLazySingleton(() => ProductApi());
GetIt.I.registerLazySingleton(() => LoginApi());
GetIt.I.registerLazySingleton(() => IPAddressInfo());
GetIt.I.registerLazySingleton(() => DeviceInfo());
GetIt.I.registerLazySingleton(() => CustomerDeviceInfoApi());
}
void setDeviceInfo() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
DeviceInfo deviceServices = GetIt.I<DeviceInfo>();
IPAddressInfo ipServices = GetIt.I<IPAddressInfo>();
prefs.setString('ipAddress', await ipServices.getIPAddress());
prefs.setString('manufacturerModel', await deviceServices.getPhoneInfo());
prefs.setString('deviceVersion', await deviceServices.getPhoneVersion());
prefs.setString('os', await deviceServices.getOperatingSystem());
prefs.setString(
'screenResolution', await deviceServices.getScreenResolution());
prefs.setString('packageOrBundle', await deviceServices.getPackageName());
prefs.setString('appVersion', await deviceServices.getAppVersion());
prefs.setString('isPhysical',
await deviceServices.isPhysicalDevice() == true ? '1' : '0');
prefs.setBool('isLoggedIn', false);
}
void main() {
// ... setup shared prefrences
// ... todo
// ... get device informaton set shared prefrences
// ... todo
// ... Setuploacator
setupLocator();
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(
create: (ctx) => OrderNotify(),
),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp(),
),
),
);
setDeviceInfo();
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool isStartHomePage = false;
#override
void initState() {
super.initState();
Future.delayed(Duration(seconds: 3), () {
// If the page has not jump over the jump page
if (!isStartHomePage) {
// Go Home and destroy the current page
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (context) => App(),
),
(Route<dynamic> rout) => false);
isStartHomePage = true;
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: AssetImage(
'assets/images/stripes_min.jpg',
),
),
),
),
Positioned(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/images/Buffet_Logo_Trans_min.png',
width: 200.0,
height: 200.0,
),
],
),
),
),
],
),
);
}
}
main.screen
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
// ... APP Helpers
import '../helpers/app_helper.dart';
// ... Pages
import '../pages/home_page.dart';
import '../pages/promotions_page.dart';
import '../pages/menu_page.dart';
import '../pages/more_page.dart';
import '../pages/orders_page.dart';
import '../pages/cart.dart';
// ... Providers
import '../providers/order_notify.dart';
// ... Widgets
import '../widgets/badge.dart';
class MainScreen extends StatefulWidget {
#override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
// Current Index set to 0
int currentTabIndex = 0;
final List<Widget> pages = [
HomePage(
key: PageStorageKey('HomePage'),
),
PromotionsPage(
key: PageStorageKey('PromoPage'),
),
MenuPage(
key: PageStorageKey('MenuOage'),
),
OrdersPage(
key: PageStorageKey('Orderpage'),
),
MorePage(
key: PageStorageKey('Morepage'),
),
Cart(
key: PageStorageKey('CartPage'),
)
];
final PageStorageBucket bucket = PageStorageBucket();
// Current page
Widget currentPage;
void setTabIndex(index) {
setState(() {
currentTabIndex = index;
currentPage = pages[index];
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).primaryColor,
elevation: 0.0,
leading: InkWell(
onTap: () {
Helper.launchUrl('tel:88007073566');
},
child: Icon(
Icons.call,
color: Colors.black,
size: 25.0,
),
),
title: Text(
'BUFFET',
style: TextStyle(fontSize: 30.0, fontFamily: 'BuffetBold'),
),
centerTitle: true,
actions: [
Container(
margin: EdgeInsets.symmetric(horizontal: 0),
width: 60,
child: Badge(
color: Colors.green,
child: IconButton(
icon: Icon(Icons.shopping_cart),
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => Cart()));
},
),
value: context.watch<OrderNotify>().items.length.toString(),
),
)
],
),
body: PageStorage(
child: pages[currentTabIndex],
bucket: bucket,
),
bottomNavigationBar: BottomNavigationBar(
onTap: (int index) {
setTabIndex(index);
},
currentIndex: currentTabIndex,
type: BottomNavigationBarType.fixed,
selectedItemColor: Theme.of(context).primaryColor,
selectedFontSize: 0,
unselectedFontSize: 0,
iconSize: 30,
elevation: 0,
backgroundColor: Colors.white,
selectedIconTheme: IconThemeData(size: 28),
unselectedItemColor: Theme.of(context).focusColor.withOpacity(1),
selectedLabelStyle:
Theme.of(context).textTheme.bodyText1.merge(TextStyle(
fontSize: 12,
fontFamily: 'BuffetBold',
)),
unselectedLabelStyle:
Theme.of(context).textTheme.button.merge(TextStyle(
fontSize: 12,
fontFamily: 'BuffetBold',
)),
showUnselectedLabels: true,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(
Icons.home_outlined,
),
label: 'Главная',
),
BottomNavigationBarItem(
icon: Icon(Icons.card_giftcard_outlined),
label: 'Акции',
),
BottomNavigationBarItem(
icon: Icon(Icons.restaurant),
label: 'Меню',
),
BottomNavigationBarItem(
icon: Icon(Icons.av_timer),
label: 'Заказы',
),
BottomNavigationBarItem(
icon: Icon(Icons.menu),
label: 'Еще',
)
],
),
);
}
}
App.dart
import 'package:flutter/material.dart';
// ... Constants
import 'constants.dart';
// ... Screens
import './screens/main_screen.dart';
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Buffet',
theme: ThemeData(
primaryColor: kPrimaryColor,
fontFamily: 'Buffet',
),
home: MainScreen(),
);
}
}
Your mistake is that you pushed MenuPage to stack in OtpScreen
Navigator.push(context,
MaterialPageRoute(builder: (context) => MenuPage()));
You should pop the otp page or navigate to MainScreen that contains your PageStorage

Black Screen appears when trying to replace the body of Scaffold when click Drawer items list

I am trying to replace the body when click item from drawer list but shows a black screen as the below GIF:
I have the following below main.dart:
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:ipet/ui/widgets/ipet_elevated_btn.dart';
import 'package:ipet/ui/widgets/ipet_gesture_detector.dart';
import 'package:ipet/ui/widgets/ipet_icon.dart';
import 'package:ipet/ui/widgets/ipet_list_tile.dart';
import 'package:ipet/ui/widgets/label.dart';
void main() {
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
final value = StateProvider<double>((ref) => 0);
final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
Color contentColor = Colors.blue;
#override
Widget build(BuildContext context) {
print('build');
return Consumer(
builder: (context, watch, child) => Scaffold(
key: scaffoldKey,
body: Stack(
children: [
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.blue[400],
Colors.blue[800],
],
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
),
),
),
SafeArea(
child: Container(
width: 200.0,
padding: EdgeInsets.all(8.0),
child: Column(
children: [
DrawerHeader(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircleAvatar(
radius: 50.0,
backgroundImage:
AssetImage("assets/images/myimage.jpg"),
),
SizedBox(
height: 10.0,
),
FittedBox(
child: IPetLabel(
ipetText: 'Mahmoud Al-Haroon',
ipetTextStyle: TextStyle(
color: Colors.white,
fontSize: 20.0,
),
),
),
],
),
),
Expanded(
child: ListView(
children: [
ListTile(
onTap: () {
contentColor = Colors.blue;
Navigator.pop(context);
},
leading: Icon(
Icons.home,
color: Colors.white,
),
title: IPetLabel(
ipetText: 'Home',
ipetTextStyle: TextStyle(
color: Colors.white,
),
),
),
ListTile(
onTap: () {},
leading: Icon(
Icons.map,
color: Colors.white,
),
title: IPetLabel(
ipetText: 'Map',
ipetTextStyle: TextStyle(
color: Colors.white,
),
),
),
IPetListTile(
ltOnTab: () {
contentColor = Colors.red;
Navigator.pop(context);
},
ltLeading: Icon(
Icons.settings,
color: Colors.white,
),
ltTitle: IPetLabel(
ipetText: 'Settings',
ipetTextStyle: TextStyle(
color: Colors.white,
),
),
),
IPetListTile(
ltOnTab: () {},
ltLeading: Icon(
Icons.star_rate,
color: Colors.white,
),
ltTitle: IPetLabel(
ipetText: 'Rate App',
ipetTextStyle: TextStyle(
color: Colors.white,
),
),
),
IPetListTile(
ltOnTab: () {},
ltLeading: Icon(
Icons.logout,
color: Colors.white,
),
ltTitle: IPetLabel(
ipetText: 'Logout',
ipetTextStyle: TextStyle(
color: Colors.white,
),
),
),
],
),
),
],
),
),
),
TweenAnimationBuilder(
tween: Tween<double>(begin: 0, end: watch(value).state),
duration: Duration(milliseconds: 500),
curve: Curves.easeIn,
builder: (_, double val, __) {
return (Transform(
alignment: Alignment.center,
transform: Matrix4.identity()
..setEntry(3, 2, 0.001)
..setEntry(0, 3, 200 * val)
..rotateY((pi / 6) * val),
child: Scaffold(
appBar: AppBar(
leading: IconButton(
onPressed: () {
watch(value).state == 0
? watch(value).state = 1
: watch(value).state = 0;
},
icon: IPetIcon(
ipetIcon: Icons.list,
ipetIconColor: Colors.white,
),
),
title: IPetLabel(ipetText: 'IPet'),
),
body: Container(
color: contentColor,
),
),
));
},
),
IPetGestureDetector(
gdOnHorizontalDragUpdate: (e) {
if (e.delta.dx > 0) {
watch(value).state = 1;
} else {
watch(value).state = 0;
}
print(e.delta.dx);
},
)
],
),
),
);
}
}
So what I need when click any item from the Drawer list I want to change the body only, for example when click settings screen just replace the body only.
Please use default app drawer:
ScafFold(
drawer: , // Your List
);
Instead of using Navigator.pop(context); use Navigator.of(context).maybePop(); and add this line
watch(value).state = 0;

Flutter variable doesn't change background color when changed?

I'm new to flutter and am trying to update the background color of a scaffold when a variable is changed. the variable is declared in another file. The reason why it needs to change? I am trying to change the background of the app to grey, a dark mode option. Any advice on why the background doesn't change when the variable does? Any advice would be appreciated, thanks!
import 'package:flutter/material.dart';
import 'package:page_transition/page_transition.dart';
import 'package:share/share.dart';
import './Widgets/DrawerSettings.dart';
void main() {
runApp(MaterialApp(
title: 'Navigation Basics',
home: FirstRoute(),
));
}
class FirstRoute extends StatefulWidget {
#override
_FirstRouteState createState() => _FirstRouteState();
}
class _FirstRouteState extends State<FirstRoute> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
drawer: Container(
width: 70,
child: ClipRRect(
borderRadius: BorderRadius.vertical(top: Radius.circular(.0)),
child: Drawer(
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 30, 0, 0),
child: Column(
children: <Widget>[
IconButton(
icon: Icon(Icons.bookmark),
onPressed: () {
Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: SavedRoute()));
},
),
IconButton(
icon: Icon(Icons.rate_review),
onPressed: () {
Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: ReviewRoute()));
},
),
IconButton(
icon: Icon(Icons.share),
onPressed: () {
Share.share('Share');
},
),
IconButton(
icon: Icon(Icons.settings),
onPressed: () {
Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: SettingsRoute()));
},
)
],
),
),
),
),
),
appBar: AppBar(
title: Text(
'Explore',
),
centerTitle: true,
backgroundColor: Colors.cyan[500],
),
body: Scaffold(
backgroundColor: DarkMode ? Colors.grey[800] : Colors.white, //Here is the code to change the background color when variable change.
body: Padding(
padding: const EdgeInsets.fromLTRB(2, 12, 2, 12),
child: Center(
child: ListView(
shrinkWrap: true,
padding: EdgeInsets.all(5.0),
children: <Widget>[
Column(
children: [
Container(
padding: EdgeInsets.fromLTRB(2, 10, 2, 0),
height: 150,
width: double.maxFinite,
child: InkWell(
onTap: () {
Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: SecondRoute()));
},
child: Card(
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(15.0),
child: Image.network(
'https://i.ytimg.com/vi/hlWiI4xVXKY/maxresdefault.jpg',
fit: BoxFit.cover,
height: 150.0,
width: 100.0,
),
),
),
),
),
],
),
),
),
),
),
);
}
}
Here is the second file
import 'package:flutter/material.dart';
class SettingsRoute extends StatefulWidget {
#override
_SettingsRouteState createState() => _SettingsRouteState();
}
bool DarkMode = false;
class _SettingsRouteState extends State<SettingsRoute> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: DarkMode ? Colors.grey[800] : Colors.white,
appBar: AppBar(
title: Text(
'Settings',
),
centerTitle: true,
),
body: ListView(
children: <Widget>[
Container(
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 20, 10, 20),
child: SwitchListTile(
title: Text(
'Dark Mode',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w400,
color: DarkMode ? Colors.white : Colors.grey[800],
),
),
value: DarkMode,
activeColor: Colors.white,
inactiveThumbColor: Colors.white,
onChanged: (bool value) {
setState(() {
DarkMode = !DarkMode;
});
},
),
),
),
],
),
),
);
}
}
You can copy paste run full code below
You can pass callback refresh to SettingsRoute and call with widget.callback()
You can see working demo below
code snippet
class _FirstRouteState extends State<FirstRoute> {
refresh() {
setState(() {});
}
...
onPressed: () {
Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: SettingsRoute(
callback: refresh,
)));
},
...
class SettingsRoute extends StatefulWidget {
final VoidCallback callback;
SettingsRoute({this.callback});
...
onChanged: (bool value) {
setState(() {
DarkMode = !DarkMode;
});
widget.callback();
},
working demo
full code
import 'package:flutter/material.dart';
import 'package:page_transition/page_transition.dart';
import 'package:share/share.dart';
void main() {
runApp(MaterialApp(
title: 'Navigation Basics',
home: FirstRoute(),
));
}
class FirstRoute extends StatefulWidget {
#override
_FirstRouteState createState() => _FirstRouteState();
}
class _FirstRouteState extends State<FirstRoute> {
refresh() {
setState(() {});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
drawer: Container(
width: 70,
child: ClipRRect(
borderRadius: BorderRadius.vertical(top: Radius.circular(.0)),
child: Drawer(
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 30, 0, 0),
child: Column(
children: <Widget>[
IconButton(
icon: Icon(Icons.bookmark),
onPressed: () {
/* Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: SavedRoute()));*/
},
),
IconButton(
icon: Icon(Icons.rate_review),
onPressed: () {
/* Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: ReviewRoute()));*/
},
),
IconButton(
icon: Icon(Icons.share),
onPressed: () {
Share.share('Share');
},
),
IconButton(
icon: Icon(Icons.settings),
onPressed: () {
Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: SettingsRoute(
callback: refresh,
)));
},
)
],
),
),
),
),
),
appBar: AppBar(
title: Text(
'Explore',
),
centerTitle: true,
backgroundColor: Colors.cyan[500],
),
body: Scaffold(
backgroundColor: DarkMode
? Colors.grey[800]
: Colors
.white, //Here is the code to change the background color when variable change.
body: Padding(
padding: const EdgeInsets.fromLTRB(2, 12, 2, 12),
child: Center(
child: ListView(
shrinkWrap: true,
padding: EdgeInsets.all(5.0),
children: <Widget>[
Column(
children: [
Container(
padding: EdgeInsets.fromLTRB(2, 10, 2, 0),
height: 150,
width: double.maxFinite,
child: InkWell(
onTap: () {
/* Navigator.push(
context,
PageTransition(
type: PageTransitionType.rightToLeft,
child: SecondRoute()));*/
},
child: Card(
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(15.0),
child: Image.network(
'https://i.ytimg.com/vi/hlWiI4xVXKY/maxresdefault.jpg',
fit: BoxFit.cover,
height: 150.0,
width: 100.0,
),
),
),
),
),
],
),
]),
),
),
),
));
}
}
class SettingsRoute extends StatefulWidget {
final VoidCallback callback;
SettingsRoute({this.callback});
#override
_SettingsRouteState createState() => _SettingsRouteState();
}
bool DarkMode = false;
class _SettingsRouteState extends State<SettingsRoute> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: DarkMode ? Colors.grey[800] : Colors.white,
appBar: AppBar(
title: Text(
'Settings',
),
centerTitle: true,
),
body: ListView(
children: <Widget>[
Container(
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 20, 10, 20),
child: SwitchListTile(
title: Text(
'Dark Mode',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w400,
color: DarkMode ? Colors.white : Colors.grey[800],
),
),
value: DarkMode,
activeColor: Colors.white,
inactiveThumbColor: Colors.white,
onChanged: (bool value) {
setState(() {
DarkMode = !DarkMode;
});
widget.callback();
},
),
),
),
],
),
),
);
}
}
You need to get the value of the DarkMode variable from a global variable like using an app state provider. Or you can send the DarkMode value as a parameter to the next page. The first one is a better use-case.
Your provider will look like this:
import 'package:flutter/material.dart';
class AppStateProvider with ChangeNotifier {
bool _darkMode = false;
bool get darkMode => this._darkMode;
void setDarkMode(bool value) {
this._darkMode = value;
}
}
You can read more from here.