How to go to a specific page using the button? Flutter - flutter

I create Welcome Page, when clicking the button I would like the user to be redirected to the home page, but when I click it gives several errors. I don't know how to program very well in flutter, can someone help me?
I tried in many ways, and they all fail. If you have to press the button to restart the APP it would also work, but I don't know how to solve it in any way
WELCOME PAGE (I would like to be redirected to HOME by clicking the button)
import 'package:flutter/material.dart';
import '../../main.dart';
import '../models/items.dart';
import '../helpers/helper.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/cupertino.dart';
void main() => runApp(Welcome());
Future<void> Return() async {
runApp(MyApp());
}
class Welcome extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: WelcomeScreen(),
);
}
}
class WelcomeScreen extends StatefulWidget {
final GlobalKey<ScaffoldState> parentScaffoldKey;
WelcomeScreen({Key key, this.parentScaffoldKey}) : super(key: key);
#override
_WelcomeScreenState createState() => _WelcomeScreenState();
}
class _WelcomeScreenState extends State<WelcomeScreen> {
List<Widget> slides = items
.map((item) => Container(
padding: EdgeInsets.symmetric(horizontal: 18.0),
child: Column(
children: <Widget>[
Flexible(
flex: 1,
fit: FlexFit.tight,
child: Image.asset(
item['image'],
fit: BoxFit.fitWidth,
width: 220.0,
alignment: Alignment.bottomCenter,
),
),
Flexible(
flex: 1,
fit: FlexFit.tight,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 30.0),
child: Column(
children: <Widget>[
Text(item['header'],
style: TextStyle(
fontSize: 50.0,
fontWeight: FontWeight.w300,
color: Color(0XFF3F3D56),
height: 2.0)),
Text(
item['description'],
style: TextStyle(
color: Colors.grey,
letterSpacing: 1.2,
fontSize: 16.0,
height: 1.3),
textAlign: TextAlign.center,
)
],
),
),
)
],
)))
.toList();
double currentPage = 0.0;
final _pageViewController = new PageController();
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: Helper.of(context).onWillPop,
child: Scaffold(
body: Stack(
alignment: AlignmentDirectional.topCenter,
children: <Widget>[
PageView.builder(
controller: _pageViewController,
itemCount: slides.length,
itemBuilder: (BuildContext context, int index) {
_pageViewController.addListener(() {
setState(() {
currentPage = _pageViewController.page;
});
});
return slides[index];
},
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
margin: EdgeInsets.only(top: 70.0),
padding: EdgeInsets.symmetric(vertical: 40.0),
)
),
Positioned(
bottom: 10,
child: RaisedButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context){
return HomeWidget();
},
highlightElevation: 2,
splashColor: Color(0xFF2F4565),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)
),
padding: EdgeInsets.symmetric(horizontal: 40),
color: Color(0XFFEA5C44),
child: Text(
"Permitir",
style: TextStyle(color: Colors.white),
),
),
)
],
),
),
);
}
}
HOMEPAGE (I would like to be redirected to that page by clicking the button on the WELCOME page)
import 'package:flutter/material.dart';
import 'package:mvc_pattern/mvc_pattern.dart';
import '../../generated/l10n.dart';
import '../controllers/home_controller.dart';
import '../elements/CardsCarouselWidget.dart';
import '../elements/CaregoriesCarouselWidget.dart';
import '../elements/DeliveryAddressBottomSheetWidget.dart';
import '../elements/GridWidget.dart';
import '../elements/ProductsCarouselWidget.dart';
import '../elements/ReviewsListWidget.dart';
import '../elements/SearchBarWidget.dart';
import '../elements/ShoppingCartButtonWidget.dart';
import '../repository/settings_repository.dart' as settingsRepo;
import '../repository/user_repository.dart';
class HomeWidget extends StatefulWidget {
final GlobalKey<ScaffoldState> parentScaffoldKey;
HomeWidget({Key key, this.parentScaffoldKey}) : super(key: key);
#override
_HomeWidgetState createState() => _HomeWidgetState();
}
class _HomeWidgetState extends StateMVC<HomeWidget> {
HomeController _con;
#override
_HomeWidgetState() : super(HomeController()) {
_con = controller;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: new IconButton(
icon: new Icon(Icons.sort, color: Theme.of(context).hintColor),
onPressed: () => widget.parentScaffoldKey.currentState.openDrawer(),
),
automaticallyImplyLeading: false,
backgroundColor: Colors.transparent,
elevation: 0,
centerTitle: true,
title: ValueListenableBuilder(
valueListenable: settingsRepo.setting,
builder: (context, value, child) {
return Text(
value.appName ?? S.of(context).home,
style: Theme.of(context).textTheme.headline6.merge(TextStyle(letterSpacing: 1.3)),
);
},
),
actions: <Widget>[
new ShoppingCartButtonWidget(iconColor: Theme.of(context).hintColor, labelColor: Theme.of(context).accentColor),
],
),
body: RefreshIndicator(
onRefresh: _con.refreshHome,
child: SingleChildScrollView(
padding: EdgeInsets.symmetric(horizontal: 0, vertical: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: SearchBarWidget(
onClickFilter: (event) {
widget.parentScaffoldKey.currentState.openEndDrawer();
},
),
),
Padding(
padding: const EdgeInsets.only(top: 15, left: 20, right: 20),
child: ListTile(
dense: true,
contentPadding: EdgeInsets.symmetric(vertical: 0),
leading: Icon(
Icons.stars,
color: Theme.of(context).hintColor,
),
trailing: IconButton(
onPressed: () {
if (currentUser.value.apiToken == null) {
_con.requestForCurrentLocation(context);
} else {
var bottomSheetController = widget.parentScaffoldKey.currentState.showBottomSheet(
(context) => DeliveryAddressBottomSheetWidget(scaffoldKey: widget.parentScaffoldKey),
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10)),
),
);
bottomSheetController.closed.then((value) {
_con.refreshHome();
});
}
},
icon: Icon(
Icons.my_location,
color: Theme.of(context).hintColor,
),
),
title: Text(
S.of(context).top_markets,
style: Theme.of(context).textTheme.headline4,
),
subtitle: Text(
S.of(context).near_to + " " + (settingsRepo.deliveryAddress.value?.address ?? S.of(context).unknown),
style: Theme.of(context).textTheme.caption,
),
),
),
CardsCarouselWidget(marketsList: _con.topMarkets, heroTag: 'home_top_markets'),
ListTile(
dense: true,
contentPadding: EdgeInsets.symmetric(horizontal: 20),
leading: Icon(
Icons.trending_up,
color: Theme.of(context).hintColor,
),
title: Text(
S.of(context).trending_this_week,
style: Theme.of(context).textTheme.headline4,
),
subtitle: Text(
S.of(context).clickOnTheProductToGetMoreDetailsAboutIt,
maxLines: 2,
style: Theme.of(context).textTheme.caption,
),
),
ProductsCarouselWidget(productsList: _con.trendingProducts, heroTag: 'home_product_carousel'),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: ListTile(
dense: true,
contentPadding: EdgeInsets.symmetric(vertical: 0),
leading: Icon(
Icons.category,
color: Theme.of(context).hintColor,
),
title: Text(
S.of(context).product_categories,
style: Theme.of(context).textTheme.headline4,
),
),
),
CategoriesCarouselWidget(
categories: _con.categories,
),
Padding(
padding: const EdgeInsets.only(left: 20, right: 20, bottom: 20),
child: ListTile(
dense: true,
contentPadding: EdgeInsets.symmetric(vertical: 0),
leading: Icon(
Icons.trending_up,
color: Theme.of(context).hintColor,
),
title: Text(
S.of(context).most_popular,
style: Theme.of(context).textTheme.headline4,
),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: GridWidget(
marketsList: _con.popularMarkets,
heroTag: 'home_markets',
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: ListTile(
dense: true,
contentPadding: EdgeInsets.symmetric(vertical: 20),
leading: Icon(
Icons.recent_actors,
color: Theme.of(context).hintColor,
),
title: Text(
S.of(context).recent_reviews,
style: Theme.of(context).textTheme.headline4,
),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: ReviewsListWidget(reviewsList: _con.recentReviews),
),
],
),
),
),
);
}
}

First you need to set up the route:
MaterialApp(
// Start the app with the "/" named route. In this case, the app starts
// on the FirstScreen widget.
initialRoute: '/',
routes: {
// When navigating to the "/" route, build the FirstScreen widget.
'/': (context) => FirstScreen(), //NOTE: Change the FirstScreen() to your own screen's class name (ex: WelcomeScreen())
// When navigating to the "/second" route, build the SecondScreen widget.
'/second': (context) => SecondScreen(), //NOTE: Change the SecondScreen() to your own screen's class name (ex: HomeWidget())
'/third': (context) => ThirdScreen(),
},
);
And then, inside your button, navigate to the page:
// Within the `FirstScreen` widget
onPressed: () {
// Navigate to the second screen using a named route.
Navigator.pushNamed(context, '/second');
}
NOTE: One of your pages must be named as / to prevent error, for the full tutorial please visit this link

Related

Navigator.push it doesn't work how can i fix it?

I created 3 files, in the second file I put it inside the Elevatedbutton, but when I press the button I don't go to the other pagethe first it has this code :
import 'package:flutter/material.dart';
import 'Firstpage.dart';
void main (){
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: FirstPage(),
);
}
}
in the second file i have :
import 'package:flutter/material.dart';
import 'planetspage.dart';
class FirstPage extends StatefulWidget {
const FirstPage({Key? key}) : super(key: key);
#override
State<FirstPage> createState() => _FirstPageState();
}
class _FirstPageState extends State<FirstPage> {
var lang = "en";
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Stack(
children: [
Image.asset(
'images/firstwal.jpg',
width: double.infinity,
fit: BoxFit.cover,
),
Container(
padding: const EdgeInsets.all(15),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
const Text(
'Explore space',
style: TextStyle(
fontSize: 35,
color: Colors.white,
fontWeight: FontWeight.w500),
),
const SizedBox(
height: 10,
),
const Text(
'a system of millions or billions of stars, together with gas and dust, held together by gravitational attraction.',
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 20,
color: Colors.white),
),
const SizedBox(
height: 30,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(30)),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 40),
color: Colors.white,
child: DropdownButton(
items: [
"en",
"ar",
]
.map((e) => DropdownMenuItem(
child: Text(e),
value: e,
))
.toList(),
onChanged: (val) {
setState(() {
lang = val.toString();
});
},
value: lang,
style:
const TextStyle(color: Colors.black87, fontSize: 20),
iconEnabledColor: Colors.black87,
)),
),
ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(30)),
child: ElevatedButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context)=> const enPlanetspage()));
},
style: ElevatedButton.styleFrom(
primary: Colors.deepPurple),
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 10, horizontal: 20),
child: Row(
children: const [
Text(
'Next',
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
Icon(Icons.navigate_next_outlined),
],
),
)),
),
],
),
],
),
),
],
),
),
);
}
}
when i press the button Navigator.push doesn't work how can i fix it?
I created 3 files, in the second file I put it inside the Elevatedbutton, but when I press the button I don't go to the other pagethe first it has this code :
Try using:
onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (context)=> const enPlanetspage()));
Check if your image files are mentioned in the pubsec.

How to Refresh page data API get data dynamically in flutter

I used the RefreshIndicator to pull to refresh the page data but it not working
This is my code!! help me to over come the issue on refresh on data
import 'dart:async';
import 'package:apitest3/services/api_manager.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'models/statusinfo.dart';
import 'package:flutter/services.dart';
class TestPage extends StatefulWidget {
const TestPage({Key? key}) : super(key: key);
#override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> {
late Future<Status> _status;
final GlobalKey<RefreshIndicatorState> _refreshIndicatorkey =
new GlobalKey<RefreshIndicatorState>();
#override
void initState() {
_status = API_Manager().getStatus();
super.initState();
WidgetsBinding.instance?.addPostFrameCallback(
(_) => _refreshIndicatorkey.currentState?.show());
}
#override
Widget build(BuildContext context) {
final key = new GlobalKey<ScaffoldState>();
return Scaffold(
body: SafeArea(
child: RefreshIndicator(
key: keyStatus,
onRefresh: () => _status,
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Colors.purple, Colors.blue])),
padding: EdgeInsets.all(4),
child: FutureBuilder<Status>(
future: _status,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
padding: EdgeInsets.all(4),
itemCount: 1,
itemBuilder: (context, index) {
var result = snapshot.data!.result.syncInfo;
return Flexible(
child: Card(
elevation: 20,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
color: Colors.indigo.shade900,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Container(
child: Text(
"Latest Block Hash ",
style: TextStyle(
fontSize: 15,
color: Colors.white),
)),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
RaisedButton.icon(
color: Colors.blueAccent,
onPressed: () {
Clipboard.setData(ClipboardData(
text: result.latestBlockHash));
key.currentState!
.showSnackBar(new SnackBar(
backgroundColor:Colors.amberAccent,
content: new Text(
"Copied to Latest Block Hash!!",
style: TextStyle(
color: Colors.red),
),
));
},
icon: Icon(
Icons.copy,
color: Colors.white,
size: 15,
),
label: Text(
"${result.latestBlockHash}",
style: TextStyle(
fontSize: 7.1,
color: Colors.white),
overflow: TextOverflow.ellipsis,
maxLines: 1,
)),
),
),
),
);
}
}
),
),
Card(
color: Colors.blueAccent,
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Container(
height: 20,
child: Row(
children: [
Text(
" ${result.latestBlockTime
.toString()}",
style: TextStyle(
fontSize: 10,
color: Colors.white),
),
],
),
],
),
),
);
});
} else
return Center(child: CircularProgressIndicator()
//CupertinoActivityIndicator()
);
},
),
),
),
),
);
}
}
I don't know what i made mistake on this code for refresh function
And all so i try to root navigation method but it pop more pages on the same page so once try to close the page it there several pages to close,
so, try to help me on proper way to pull refresh on the page.
You need to update the state after refreshing on onRefresh callback. Currently, you are just assigning it to a Future variable.
This is a simple way to do it.
RefreshIndicator(
onRefresh: () { setState((){
// Update your data here
}); },
child: ...
)

confused about setState inside onTap Flutter

I've been trying to learn Flutter and this part got me really confused. Thanks a million for your help.
I wanted to return data (an object) to the first screen from the second screen. I did successfully thanks to posts I read from the internet but haven't managed to fully understand. Specifically: Why do I need to assign categoryData to the returned object then again assign it to categoryCard? Why can't I do it directly by assigning categoryCard to the returned Object? This is code that works:
First screen:
SizedBox(
height: 95,
child: GestureDetector(
onTap: () async {
final categoryData =
await Navigator.pushNamed(context, '/EditCategory');
setState(() => categoryCard = categoryData);
},
child: categoryCard),
),
Second screen:
return Card(
child: ListTile(
title: Text('${myText[index]}'),
leading: myIcon[index],
trailing: Icon(Icons.arrow_forward_ios),
onTap: () {
Navigator.pop(
context,
CategoryCard(
categoryIcon: myIcon[index],
categoryText: Text(
'${myText[index]}',
style: TextStyle(fontSize: 20),
)));
},
),
);
Code I think should work but doesn't
First screen:
SizedBox(
height: 95,
child: GestureDetector(
onTap: () {
setState(() async {
CategoryCard categoryCard =
await Navigator.pushNamed(context, '/EditCategory');
});
},
child: categoryCard),
),
Second screen is the same
This is the entire code of the first and second screen in case you'd like to know:
First:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'MyApp.dart';
class Input extends StatefulWidget {
#override
_InputState createState() => _InputState();
}
class _InputState extends State<Input> {
CategoryCard categoryCard = CategoryCard();
final _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color.fromRGBO(210, 234, 251, 1),
appBar: appBarInEx(),
body: TabBarView(
children: [
ListView(
children: [
Form(
key: _formKey,
child: Column(
children: [
TextFormField(
validator: (value) {
if (value.isEmpty) {
return 'Please enter the value';
}
return null;
},
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: ElevatedButton(
onPressed: () {
if (_formKey.currentState.validate()) {
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Processing Data')));
}
},
child: Text('Submit'),
),
),
],
),
),
SizedBox(
height: 150,
child: Card(
color: Color.fromRGBO(254, 228, 194, 1),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
SizedBox(
height: 20,
),
Text(
'Amount',
style: TextStyle(fontSize: 30),
),
SizedBox(
height: 15,
),
Text(r'0$',
style: TextStyle(
fontSize: 30,
)),
Text('_____________________________________',
style: TextStyle(
fontSize: 15,
))
],
),
),
),
),
SizedBox(
height: 95,
child: GestureDetector(
onTap: () async {
final categoryData =
await Navigator.pushNamed(context, '/EditCategory');
setState(() => categoryCard = categoryData);
},
child: categoryCard),
),
SizedBox(
height: 95,
child: Card(
color: Color.fromRGBO(254, 228, 194, 1),
child: ListTile(
contentPadding:
EdgeInsets.symmetric(vertical: 18, horizontal: 16),
title: Text(
'Note',
style: TextStyle(fontSize: 20),
),
leading: Icon(Icons.description_outlined, size: 40),
trailing: Icon(
Icons.arrow_forward_ios_outlined,
size: 30,
),
),
),
),
SizedBox(
height: 95,
child: Card(
color: Color.fromRGBO(254, 228, 194, 1),
child: ListTile(
contentPadding:
EdgeInsets.symmetric(vertical: 18, horizontal: 16),
title: Text(
'Date',
style: TextStyle(fontSize: 20),
),
leading: Icon(Icons.event, size: 40),
trailing: Icon(
Icons.arrow_forward_ios_outlined,
size: 30,
),
),
),
),
Container(
margin: EdgeInsets.fromLTRB(30, 70, 30, 0),
child: Padding(
padding: const EdgeInsets.all(18.0),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
side: BorderSide(color: Colors.red)),
elevation: 10,
color: Colors.lime,
onPressed: () {
Navigator.pushNamed(context, '/');
},
textColor: Colors.white,
child: Text(
'Save',
style: TextStyle(fontSize: 40),
),
),
),
)
],
),
Container()
],
),
);
}
}
class CategoryCard extends StatelessWidget {
final Text categoryText;
final Icon categoryIcon;
CategoryCard(
{Key key,
this.categoryText = const Text(
'Category',
style: TextStyle(fontSize: 20),
),
this.categoryIcon = const Icon(
Icons.category_outlined,
size: 40,
)})
: super(key: key);
#override
Widget build(BuildContext context) {
return Card(
color: Color.fromRGBO(254, 228, 194, 1),
child: ListTile(
contentPadding: EdgeInsets.symmetric(vertical: 18, horizontal: 16),
title: categoryText,
leading: categoryIcon,
trailing: Icon(
Icons.arrow_forward_ios_outlined,
size: 30,
),
),
);
}
}
Second:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:material_floating_search_bar/material_floating_search_bar.dart';
import 'Input.dart';
import 'MyApp.dart';
class EditCategory extends StatefulWidget {
#override
_EditCategoryState createState() => _EditCategoryState();
}
class _EditCategoryState extends State<EditCategory> {
List<String> myText = [
'Add Category',
'Cosmetic',
'Education',
'Clothes',
'Food',
'Cosmetic',
'Education',
'Clothes',
'Food'
];
List<Widget> myIcon = [
Icon(Icons.add_circle_outline),
Icon(Icons.no_food_outlined),
Icon(Icons.face),
Icon(Icons.book_outlined),
Icon(Icons.g_translate),
Icon(Icons.no_food_outlined),
Icon(Icons.face),
Icon(Icons.book_outlined),
Icon(Icons.g_translate),
];
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
backgroundColor: Color.fromRGBO(210, 234, 251, 1),
appBar: appBarInEx(),
body: TabBarView(
children: [
Column(
children: [
FloatingSearchAppBar(
title: const Text('Enter Category Name'),
transitionDuration: const Duration(milliseconds: 800),
color: Colors.orangeAccent.shade100,
colorOnScroll: Colors.greenAccent.shade200,
height: 55,
),
Expanded(
child: ListView.builder(
itemCount: myText.length,
itemBuilder: (context, index) {
if (index == 0) {
return SizedBox(
height: 90,
child: Card(
child: ListTile(
title: Text('${myText[index]}'),
leading: myIcon[index],
trailing: Icon(Icons.arrow_forward_ios),
),
));
}
return Card(
child: ListTile(
title: Text('${myText[index]}'),
leading: myIcon[index],
trailing: Icon(Icons.arrow_forward_ios),
onTap: () {
Navigator.pop(
context,
CategoryCard(
categoryIcon: myIcon[index],
categoryText: Text(
'${myText[index]}',
style: TextStyle(fontSize: 20),
)));
},
),
);
},
)),
],
),
Container()
],
),
),
);
}
}
The good code waits for the onTap and assign the result into a local variable. Then it uses setState to assign the local variable into the instance field.
Why do I need to assign categoryData to the returned object then again assign it to categoryCard? Why can't I do it directly by assigning categoryCard to the returned Object?
You can do that actually, this will work:
GestureDetector(
onTap: () async {
categoryData = await Navigator.push(...);
setState(() {});
},
),
Basically setState tells Flutter to rebuild your widget, it's not strictly required to perform state setting within the callback.
Regarding bad code: you use setState with an async callback so Flutter will just rebuild your widget immediately at that moment, it doesn't wait for your async operation to complete. At the time of rebuild, categoryData has the old value so nothing changes on the screen. When user triggers onTap on the second screen and pops back to the first, categoryData is updated with the new value but your widget is not rebuilt so it still shows outdated data.

Acessing List items on another class

Hi I would like to know how can I access the items of a list on a different class where the list was created.Particularly i want to access items of the restaurantList on the Restaurant Screen class.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:projectfooddelivery/Src/models/restaurant.dart';
List<Restaurant> restaurantList=[
Restaurant(image:"kfcloja.jpg",distance: "2 miles away",location:"Shoprite do magoanine",restaurantName: "KFC"),
Restaurant(image:"dominos.jpg",distance: "0.9 miles away",location:"Downtown",restaurantName: "Dominos"),
Restaurant(image:"kfclogo.png",distance: "2 miles away",location:"Shoprite do magoanine",restaurantName: "KFC"),
];//I would like to access the items on the list
class RestaurantWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
height: 350,
child: ListView.builder(
scrollDirection: Axis.vertical,
itemCount: restaurantList.length,
itemBuilder: (_, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(
width: 1.0,
color: Colors.grey[100]
),
borderRadius: BorderRadius.circular(20)
),
child: Row(
children: <Widget>[
Container(
width: 150,
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Image.asset("images/${restaurantList[index].image}",fit:BoxFit.cover ,)
)
),
Padding(
padding: const EdgeInsets.all(3.0),
child: Container(
padding: EdgeInsets.all(2),
height: 70,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("${restaurantList[index].restaurantName}",style: TextStyle(fontWeight: FontWeight.bold),),
Row(
children: <Widget>[
Icon(Icons.star,size: 15,color:Colors.yellowAccent,),
Icon(Icons.star,size: 15,color:Colors.yellowAccent),
Icon(Icons.star,size: 15,color:Colors.yellowAccent),
Icon(Icons.star,size: 15,color:Colors.yellowAccent),
Icon(Icons.star_half,size: 15,color:Colors.yellowAccent),
],
),
Text("${restaurantList[index].location}"),
Text("${restaurantList[index].distance}"),
],
),
),
),
],
),
),
);
},
),
);
}
}
In this class
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:projectfooddelivery/Src/widgets/menu_widget.dart';
import 'package:smooth_star_rating/smooth_star_rating.dart';
class RestaurantScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: 400,
child: Column(
children: <Widget>[
Stack(
children: <Widget>[
Image.asset(
"images/kfcloja.jpg",
fit: BoxFit.cover,
),
Positioned(
child: IconButton(
icon: Icon(Icons.keyboard_arrow_left,size: 40,color: Colors.white,),
onPressed: (){},
),
top: 15,
)
],
),
Padding(
padding: const EdgeInsets.only(top: 14, left: 14, right: 14),
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Restaurant KFC",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
Text(
"0.2 miles away",
style: TextStyle(
fontSize: 16,
),
),
],
),
Align(
alignment: Alignment.topLeft,
child: SmoothStarRating(
allowHalfRating: false,
starCount: 5,
size: 20.0,
filledIconData: Icons.blur_off,
halfFilledIconData: Icons.blur_on,
color: Colors.yellowAccent,
borderColor: Colors.yellowAccent,
spacing: 0.0),
),
Align(
alignment: Alignment.topLeft,
child: Text("200 Main St, New york"),
),
Padding(
padding: const EdgeInsets.only(
left: 30, right: 30, top: 20, bottom: 5),
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
FlatButton.icon(
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(10.0),
),
color: Theme.of(context).primaryColor,
icon: Icon(
Icons.rate_review,
color: Colors.white,
),
label: Text(
'Reviews',
style: TextStyle(color: Colors.white),
),
onPressed: () {},
),
FlatButton.icon(
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(10.0),
),
color: Theme.of(context).primaryColor,
icon: Icon(
Icons.contact_phone,
color: Colors.white,
),
label: Text(
'Contact',
style: TextStyle(color: Colors.white),
),
onPressed: () {},
)
],
),
),
),
Text(
"Menu",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20),
),
MenuWidget(),
],
)
),
)
],
),
),
);
}
}
You can send and receive the data from one screen to another as follow , you need to use the Navigator for it , In below example i am sending the data from class A to class B as follow
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => B(bean: restaurantList[index])), //// HERE B IS THE CLASS ON WHICH YOU NEED TO CARRY DATA FROM CLASS A
);
And inside the B class you need to create the contrsutor to receive the data from A like below
class B extends StatefulWidget {
Restaurant bean;
B ({Key key, #required this.bean}) : super(key: key); ////YOU WILL GET THE DATA HERE FROM THE CONSTRUCTOR , AND USE IT INSIDE THE CLASS LIKE "widget.bean"
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return _B();
}
}
And please check the example of it to pass data from one class to another
A class which send data to B class
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'B.dart';
import 'Fields.dart';
class A extends StatefulWidget {
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return _A();
}
}
class _A extends State<A> {
Widget build(BuildContext context) {
return MaterialApp(
title: 'Screen A',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.red,
accentColor: Color(0xFFFEF9EB),
),
home: Scaffold(
appBar: new AppBar(),
body: Container(
margin: EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: Text("Screen A"),
),
Expanded(
child: ListView.builder(
itemCount: fields.length,
itemBuilder: (BuildContext ctxt, int index) {
return ListTile(
title: new Text("Rating #${fields[index].rating}"),
subtitle: new Text(fields[index].title),
onTap: (){
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => B(bean: fields [index])), //// HERE B IS THE CLASS ON WHICH YOU NEED TO CARRY DATA FROM CLASS A
);
},
);
}),
)
],
),
)));
}
}
List<Fields> fields = [
new Fields(
'One',
1,
),
new Fields(
'Two',
2,
),
new Fields(
'Three',
3,
),
new Fields(
'Four',
4,
),
new Fields(
'Five',
5,
),
];
Now check B class which receive the data from A class
import 'package:flutter/material.dart';
import 'Fields.dart';
class B extends StatefulWidget{
Fields bean;
B ({Key key, #required this.bean}) : super(key: key); ////YOU WILL GET THE DATA HERE FROM THE CONSTRUCTOR , AND USE IT INSIDE THE CLASS LIKE "widget.bean"
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return _B ();
}
}
class _B extends State<B> {
#override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
title: 'Screen A',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.red,
accentColor: Color(0xFFFEF9EB),
),
home: Scaffold(
appBar: new AppBar(),
body: Container(
margin: EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: Center(
child: Text("Screen B" ,style: TextStyle(fontSize: 20.0),),
)
),
Text("Rating=>>> ${widget.bean.rating} and Title ${widget.bean.title} ")
],
),
)));
}
}
And I have used the Pojo class for the list ,please check it once
Fields.dart
class Fields {
final String title;
final int rating;
Fields(this.title, this.rating);
}
And the output of the above program as follow.

How to change a bottom navigation bar icon in the setState() function in flutter?

I'm building a food ordering app in flutter. What I want is, when the user adds items to the cart, I want the cart icon in the bottom navigation bar to obtain a red dot on top to notify the user of the addition of items to the cart.
To achieve this, I have created a global variable called no_of_cart_items and when the user adds an item to the cart, I increment this variable in the setState() function as follows:
setState(() {
GlobalVariables.no_of_cart_items+=1;
// change icon here
});
In this setState() function, I wish to change the icon in the bottom navigation bar. How should I do this?
Thank you.
FULL CODE
This is main.dart
//import lines
void main() => runApp(CanteenApp());
class CanteenApp extends StatefulWidget {
#override
_CanteenAppState createState() => _CanteenAppState();
}
class _CanteenAppState extends State<CanteenApp> {
int _currentindex=0; // index of bottom tab
int admin=GlobalVariables.admin;
BottomNavigationBadge badger = new BottomNavigationBadge(
backgroundColor: Colors.red,
badgeShape: BottomNavigationBadgeShape.circle,
textColor: Colors.white,
position: BottomNavigationBadgePosition.topRight,
textSize: 8);
Widget callpage(int currentIndex) {
switch (currentIndex) {
case 0: return UserProfile();
case 1: return Menu();
case 2: return Cart();
break;
default: return UserProfile();
}
}
#override
Widget build(BuildContext context) {
if(admin==1 && _currentindex==2) {
//if you're the admin and have called the history page
return MaterialApp(
debugShowCheckedModeBanner: false,
home: DefaultTabController(
length: 2,
child: Scaffold(
resizeToAvoidBottomPadding: false,
appBar: PreferredSize(
preferredSize: Size.fromHeight(80.0),
child: AppBar(
bottom: TabBar(
indicatorColor: Colors.white,
indicatorWeight: 5,
tabs: <Widget>[
Tab(
child: Align(
alignment: Alignment.center,
child: Text(
'Order History',
style: TextStyle(
fontSize: 20
),
)
)
),
Tab(
child: Align(
alignment: Alignment.center,
child: Text(
'Deposit / Withdraw\nHistory',
style: TextStyle(
fontSize: 17
),
textAlign: TextAlign.center,
)
)
),
],
),
),
),
body: TabBarView(
children: <Widget>[
AdminOrderHistory(),
DepositWithdrawHistory()
],
),
bottomNavigationBar: BottomNavigationBar(
elevation: 10,
currentIndex: _currentindex,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.account_circle),
title: Text('Profile'),
),
BottomNavigationBarItem(
icon: Icon(Icons.restaurant_menu),
title: Text('Menu'),
),
BottomNavigationBarItem(
icon: Icon(Icons.history),
title: Text('History'),
),
],
onTap: (index){
setState(() {
_currentindex=index;
});
}
),
),
),
theme: appTheme,
);
}
else if(admin==1){
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
resizeToAvoidBottomPadding: false,
body: callpage(_currentindex),
bottomNavigationBar: BottomNavigationBar(
elevation: 10,
currentIndex: _currentindex,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.account_circle),
title: Text('Profile'),
),
BottomNavigationBarItem(
icon: Icon(Icons.restaurant_menu),
title: Text('Menu'),
),
BottomNavigationBarItem(
icon: Icon(Icons.history),
title: Text('History'),
),
],
onTap: (index){
setState(() {
_currentindex=index;
});
}
),
),
theme: appTheme,
);
}
else if(admin==0){
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
resizeToAvoidBottomPadding: false,
body: callpage(_currentindex),
bottomNavigationBar:BottomNavigationBar(
elevation: 10,
currentIndex: _currentindex,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.account_circle),
title: Text('Profile'),
),
BottomNavigationBarItem(
icon: Icon(Icons.restaurant_menu),
title: Text('Menu'),
),
BottomNavigationBarItem(
title: Text('Cart'),
icon: Badge(
showBadge: true,
badgeContent: Text(
GlobalVariables.no_of_cart_items.toString(),
style: TextStyle(
color: Colors.white
),
),
child: Icon(Icons.shopping_cart)
)
),
],
onTap: (index){
setState(() {
_currentindex=index;
});
}
),
),
theme: appTheme,
);
}
}
}
This is menu.dart
//import lines
int admin=GlobalVariables.admin;
List snacksmenuitems=[
['Vada Pav', 15],
['Samosa Pav', 15],
['Punjabi Samosa', 25],
['Pav', 5]
];
List ricemenuitems=[
['Fried Rice', 62],
['Schezwan Rice', 69],
['Singapore Rice', 69],
['Manchow Rice', 73],
];
class Menu extends StatefulWidget {
#override
_MenuState createState() => _MenuState();
}
class _MenuState extends State<Menu> {
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
MenuTopPart(),
MenuBottomPart(),
],
);
}
}
Color firstColor = Color(0xFFF47D15);
Color secondColor = Color(0xFFEF772C);
class MenuTopPart extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
ClipPath(
clipper: CustomShapeClipper(),
child: Container(
height:140.0,
width:MediaQuery.of(context).size.width,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [firstColor, secondColor],
)
),
child: Column(
children: <Widget>[
SizedBox(height: 53.0),
Text(
'MENU',
style: TextStyle(
fontSize: 30.0,
color: Colors.white,
),
textAlign: TextAlign.center,
),
],
)
)
)
],
);
}
}
class MenuBottomPart extends StatefulWidget {
#override
_MenuBottomPartState createState() => _MenuBottomPartState();
}
class _MenuBottomPartState extends State<MenuBottomPart> {
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
SizedBox(height: 10),
SizedBox(height: 10),
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 10),
child: Container(
height: MediaQuery
.of(context)
.size
.height * 0.60,
child: ListView(
padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
scrollDirection: Axis.vertical,
children: <Widget>[
Card(
child: Padding(
padding: const EdgeInsets.fromLTRB(5, 0, 5, 0),
child: ExpansionTile(
title: Text('SNACKS'),
children: snacksmenuitems.map((menuitem) {
//print(menuitem);
return MenuItem(menuitem: menuitem);
/*SizedBox(height:10),
MenuItem(),
SizedBox(height:10),
MenuItem(),
SizedBox(height:10),
MenuItem()*/
}).toList()
),
)
),
SizedBox(height: 10),
Card(
child: Padding(
padding: const EdgeInsets.fromLTRB(5, 0, 5, 0),
child: ExpansionTile(
title: Text('RICE ITEMS'),
children: ricemenuitems.map((menuitem) {
//print(menuitem);
return MenuItem(menuitem: menuitem);
/*SizedBox(height:10),
MenuItem(),
SizedBox(height:10),
MenuItem(),
SizedBox(height:10),
MenuItem()*/
}).toList()
),
)
)
]
),
),
)
]
);
}
}
class MenuItem extends StatefulWidget {
List menuitem=[];
MenuItem({Key key, this.menuitem}): super(key: key);
#override
_MenuItemState createState() => _MenuItemState();
}
class _MenuItemState extends State<MenuItem> {
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(bottom: 10),
decoration: BoxDecoration(
border: Border.all(color: Colors.black12),
borderRadius: BorderRadius.all(Radius.circular(10))
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Image(
image: NetworkImage('https://www.whiskaffair.com/wp-content/uploads/2018/08/Mumbai-Pav-Bhaji-4.jpg'),
width: 80,
height: 80
),
SizedBox(width:10),
Padding(
padding: const EdgeInsets.fromLTRB(0, 5, 0, 0),
child: Container(
width:190,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
widget.menuitem[0],
style: TextStyle(
fontSize:19,
color: Colors.grey[900]
),
),
SizedBox(height:5.0),
Padding(
padding: const EdgeInsets.fromLTRB(0, 10, 0, 0),
child: Row(
children: <Widget>[
Row(
children: <Widget>[
Text(
'₹',
style: TextStyle(
fontSize: 15,
color: Colors.grey[800]
),
),
Text(
widget.menuitem[1].toString(),
style: TextStyle(
fontSize: 15,
color: Colors.grey[800]
),
)
],
),
SizedBox(width:70),
Container(
child: Row(
children: <Widget>[
SizedBox(
width:30,
height:30,
child: FloatingActionButton(
onPressed: (){
setState(() {
if(GlobalVariables.allcartitems[widget.menuitem[0]][0]>0){
GlobalVariables.no_of_cart_items-=1;
GlobalVariables.allcartitems[widget.menuitem[0]][0]-=1;
GlobalVariables.totalcost-=GlobalVariables.allcartitems[widget.menuitem[0]][1];
// CHECK IF CART HAS NO ITEMS AND REMOVE BADGE HERE
}
});
},
elevation: 1,
child: Icon(Icons.remove, size: 18),
backgroundColor: Colors.red[300],
mini: true,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(5.0))),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(5, 0, 5, 0),
child: Text(
GlobalVariables.allcartitems[widget.menuitem[0]][0].toString(),
style: TextStyle(
fontSize: 18
),
),
),
SizedBox(
width:30,
height:30,
child: FloatingActionButton(
onPressed: (){
setState(() {
GlobalVariables.no_of_cart_items+=1;
GlobalVariables.allcartitems[widget.menuitem[0]][0]+=1;
GlobalVariables.totalcost+=GlobalVariables.allcartitems[widget.menuitem[0]][1];
// SET BADGE HERE
});
},
elevation: 1,
child: Icon(Icons.add, size: 20),
backgroundColor: Colors.green[300],
mini:true,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(5.0))),
),
)
],
)
)
],
),
),
],
),
),
)
],
),
);
}
}
This is cart.dart:
import 'dart:convert';
import 'package:canteen_app/pages/globalvar.dart';
import 'package:canteen_app/pages/globalvar.dart' as prefix0;
import 'package:canteen_app/pages/orderReceipt.dart';
import 'package:flutter/material.dart';
import 'package:canteen_app/pages/CustomShapeClipper.dart';
import 'package:http/http.dart' as http;
import 'package:intl/intl.dart';
class Cart extends StatefulWidget {
#override
_CartState createState() => _CartState();
}
class _CartState extends State<Cart> {
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
CartTopPart(),
CartBottomPart()
],
);
}
}
class CartTopPart extends StatefulWidget {
#override
_CartTopPartState createState() => _CartTopPartState();
}
Color firstColor = Color(0xFFF47D15);
Color secondColor = Color(0xFFEF772C);
class _CartTopPartState extends State<CartTopPart> {
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
ClipPath(
clipper: CustomShapeClipper(),
child: Container(
height:140.0,
width:MediaQuery.of(context).size.width,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [firstColor, secondColor],
)
),
child: Column(
children: <Widget>[
SizedBox(height: 53.0),
Text(
'CART',
style: TextStyle(
fontSize: 30.0,
color: Colors.white,
),
textAlign: TextAlign.center,
),
],
)
)
)
],
);
}
}
var cartmenuitems = GlobalVariables.allcartitems.keys.toList();
class CartBottomPart extends StatefulWidget {
#override
_CartBottomPartState createState() => _CartBottomPartState();
}
class _CartBottomPartState extends State<CartBottomPart> {
bool _isLoading=false;
createAlertDialog(BuildContext context, String errormessage){
return showDialog(
context: context,
builder: (context){
return AlertDialog(
content: Text(errormessage)
);
}
);
}
#override
Widget build(BuildContext context) {
if(GlobalVariables.no_of_cart_items>0) {
return _isLoading==true ? Center(child: CircularProgressIndicator()) : Padding(
padding: const EdgeInsets.fromLTRB(20, 10, 20, 10),
child: Column(
children: <Widget>[
Container(
height: MediaQuery
.of(context)
.size
.height * 0.40,
child: ListView(
padding: EdgeInsets.fromLTRB(0, 10, 0, 0),
scrollDirection: Axis.vertical,
children: cartmenuitems.map((menuitem) {
//print(cartmenuitems);
// print(GlobalVariables.allcartitems[menuitem]);
//if(GlobalVariables.allcartitems[menuitem]>=1) {
//print('heyy');
return CartOrderDish(menuitem: menuitem);
//}
}).toList()
),
),
Divider(
color: Colors.black
),
Row(
children: <Widget>[
Text(
'Total Amount:',
style: TextStyle(
fontSize: 20
),
),
SizedBox(width: 140),
Row(
children: <Widget>[
Text(
'₹',
style: TextStyle(
fontSize: 20
),
),
Text(
GlobalVariables.totalcost.toString(),
style: TextStyle(
fontSize: 20
)
)
],
)
],
),
SizedBox(height: 5),
Align(
alignment: Alignment.centerLeft,
child: Text(
'(Inclusive of GST)',
style: TextStyle(
fontSize: 15
),
),
),
SizedBox(height: 18),
RaisedButton(
onPressed: () {
if((GlobalVariables.accountbalance-GlobalVariables.totalcost)<0){
createAlertDialog(context, "Whoops! The total cost exceeds your account balance!\n\nYour account balance can be updated at the CASH COUNTER.");
}
else {
setState(() {
_isLoading = true;
});
// creating a list of all cart items to send to php
List cart = [];
cartmenuitems.map((menuitem) {
if (GlobalVariables.allcartitems[menuitem][0] > 0) {
cart.add([menuitem, GlobalVariables.allcartitems[menuitem][0], GlobalVariables.allcartitems[menuitem][1] * GlobalVariables.allcartitems[menuitem][0]]);
}
}).toList();
print(jsonEncode(cart));
Future placeOrderFunction() async {
print(GlobalVariables.username);
final response = await http.post(
"https://kjscecanteenapp.000webhostapp.com/place_order_sys.php",
body: {
"cart": json.encode(cart),
"username": GlobalVariables.username
});
// print(response.body);
var decodedResponse = json.decode(response.body);
print(decodedResponse);
setState(() {
_isLoading = false;
});
if (decodedResponse['error'] != -1) {
// means no error
int orderId=decodedResponse['error'];
int cost=GlobalVariables.totalcost;
GlobalVariables.no_of_cart_items = 0;
String date=DateFormat('dd-MMM-yyyy').format(DateTime.now());
cartmenuitems.map((menuitem) {
if (GlobalVariables.allcartitems[menuitem][0] > 0) {
GlobalVariables.allcartitems[menuitem][0] = 0;
}
});
GlobalVariables ob = new GlobalVariables();
ob.resetcart();
GlobalVariables.accountbalance -= GlobalVariables.totalcost;
GlobalVariables.totalcost = 0;
Navigator.of(context)
.push(MaterialPageRoute<Null>(
builder: (BuildContext context) {
return new OrderReceipt(orderId: orderId, cost: cost, date: date, cart: cart);
}));
}
else{
createAlertDialog(context, "There was some error during the order placement. Don't worry tho try again in a few seconds!");
}
}
placeOrderFunction();
}
},
elevation: 5.0,
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0)),
padding: const EdgeInsets.all(0.0),
child: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: <Color>[
Color(0xFF0083B0),
Color(0xFF00B4DB),
]
)
),
padding: const EdgeInsets.fromLTRB(40, 15, 40, 15),
child: Text(
'Place Order',
style: TextStyle(
fontSize: 20
),
),
)
)
],
),
);
}
else {
return Padding(
padding: const EdgeInsets.all(20.0),
child: Container(
height: MediaQuery.of(context).size.height*0.6,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'Please add some items into your cart.',
style: TextStyle(
fontSize: 20,
),
textAlign: TextAlign.center,
),
],
),
),
);
}
}
}
class CartOrderDish extends StatefulWidget {
String menuitem;
CartOrderDish({Key key, this.menuitem}): super(key: key);
#override
_CartOrderDishState createState() => _CartOrderDishState();
}
class _CartOrderDishState extends State<CartOrderDish> {
#override
Widget build(BuildContext context) {
if(GlobalVariables.allcartitems[widget.menuitem][0]>0) {
int price=GlobalVariables.allcartitems[widget.menuitem][0]*GlobalVariables.allcartitems[widget.menuitem][1];
return Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 10),
child: Row(
children: <Widget>[
Expanded(
child: Text(
widget.menuitem,
style: TextStyle(
fontSize: 20
),
),
),
SizedBox(width: 50),
Container(
child: Row(
children: <Widget>[
SizedBox(
width: 30,
height: 30,
child: FloatingActionButton(
heroTag: 'fab1',
elevation: 1,
child: Icon(Icons.remove, size: 18),
backgroundColor: Colors.red[300],
mini: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0))),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(5, 0, 5, 0),
child: Text(
GlobalVariables.allcartitems[widget.menuitem][0].toString(),
style: TextStyle(
fontSize: 18
),
),
),
SizedBox(
width: 30,
height: 30,
child: FloatingActionButton(
heroTag: 'fab2',
elevation: 1,
child: Icon(Icons.add, size: 20),
backgroundColor: Colors.green[300],
mini: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0))),
),
)
],
)
),
SizedBox(width: 50),
Row(
children: <Widget>[
Text(
'₹',
style: TextStyle(
fontSize: 20
),
),
Text(
price.toString(),
style: TextStyle(
fontSize:20
)
)
],
)
],
),
);
}
else{
return Container();
}
}
}
Instead of changing the entire icon to indicate items added to cart, you could use Badge
Badge package: https://pub.dev/packages/badges
Update-1: For implementing the badges:
var p1badge = false;
var p2badge = false;
List<BottomNavigationBarItem> buildBottomNavBarItems() {
return [
BottomNavigationBarItem(
icon: Badge(
showBadge: p1badge,
child: Icon(Icons.filter_1),
),
title: Text('Page-1')),
BottomNavigationBarItem(
icon: Badge(
showBadge: p2badge,
child: Icon(Icons.filter_2),
),
title: Text('Page-2'))
];
}
Use a VoidCallback to update the badge:
class Page1 extends StatelessWidget {
VoidCallback onP1Badge;
Page1({this.onP1Badge});
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
RaisedButton(
child: Text('P1 BADGE'),
onPressed: () {onP1Badge();},
),
],
);
}
}
Change the value of p1badge to true and call setState():
pages = [
Page1(
onP1Badge: () {
p1badge = true;
setState(() {});
},
),
Page2()
];
Update-2: Check this out: https://github.com/TheArhaam/Flutter-BottomNavigationBar-Badge
GIF: