How to update main class widget from page in Flutter - flutter

Here is my main class with pageview
class EditInvoice extends StatefulWidget {
#override
_EditInvoiceState createState() => _EditInvoiceState();
}
class _EditInvoiceState extends State<EditInvoice> {
String strTotal = '0';
#override
void initState() {
super.initState();
}
PageController pageController = PageController(
initialPage: 0,
keepPage: true,
);
Widget buildPageView() {
return PageView(
controller: pageController,
children: <Widget>[
AddItems(),
],
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
floatingActionButton: FloatingActionButton(
onPressed: () {},
backgroundColor: Colors.orange[600],
elevation: 2.0,
child: Icon(
Icons.check,
color: Colors.white,
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.black, //change your color here
),
automaticallyImplyLeading: false,
toolbarHeight: 140.0,
centerTitle: true,
title: Column(
children: <Widget>[
Row(
children: <Widget>[
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back)),
Padding(padding: EdgeInsets.only(left: 30.0)),
Align(
alignment: Alignment.center,
child: Text(
strTotal,
style: TextStyle(color: Colors.black),
),
)
],
),
],
),
backgroundColor: Colors.white,
),
body: buildPageView(),
);
}
}
class AddItems extends StatefulWidget {
#override
_AddItemsState createState() => _AddItemsState();
}
class _AddItemsState extends State<AddItems> {
#override
Widget build(BuildContext context) {
var items = Padding(
padding: EdgeInsets.only(left: 20.0, right: 20.0),
child: TextFormField(
decoration: InputDecoration(
labelText: 'Amount',
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5)),
),
),
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 15,
),
cursorColor: Colors.black,
keyboardType: TextInputType.phone,
));
return Container(
child: Card(
child: Padding(
padding: EdgeInsets.only(top: 10, bottom: 5.0, left: 10.0, right: 10.0),
child: SingleChildScrollView(
child: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Text(
'Add Items',
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
),
items,
])))),
);
}
}
I am implementing pageview in my Flutter application. I want to update the amount in main class whenever user entered value in TextFormField from pageview.
Here AddItems is the page added with pageview and EditInvoice is the main class.
I am new to Flutter application development.

You can use the Provider Pattern:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ProviderTest with ChangeNotifier {
String amount = '';
void updateAmount(String newAmount) {
amount = newAmount;
notifyListeners();
}
}
class EditInvoice extends StatefulWidget {
#override
_EditInvoiceState createState() => _EditInvoiceState();
}
class _EditInvoiceState extends State<EditInvoice> {
#override
void initState() {
super.initState();
}
PageController pageController = PageController(
initialPage: 0,
keepPage: true,
);
Widget buildPageView() {
return PageView(
controller: pageController,
children: <Widget>[
AddItems(),
],
);
}
#override
Widget build(BuildContext context) {
var providerTest = Provider.of<ProviderTest>(context);
return Scaffold(
backgroundColor: Colors.white,
floatingActionButton: FloatingActionButton(
onPressed: () {},
backgroundColor: Colors.orange[600],
elevation: 2.0,
child: Icon(
Icons.check,
color: Colors.white,
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.black, //change your color here
),
automaticallyImplyLeading: false,
toolbarHeight: 140.0,
centerTitle: true,
title: Column(
children: <Widget>[
Row(
children: <Widget>[
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back)),
Padding(padding: EdgeInsets.only(left: 30.0)),
Align(
alignment: Alignment.center,
child: Text(
providerTest.amount.toString(),
style: TextStyle(color: Colors.black),
),
)
],
),
],
),
backgroundColor: Colors.white,
),
body: buildPageView(),
);
}
}
class AddItems extends StatefulWidget {
#override
_AddItemsState createState() => _AddItemsState();
}
class _AddItemsState extends State<AddItems> {
#override
Widget build(BuildContext context) {
var providerTest = Provider.of<ProviderTest>(context, listen: false);
var items = Padding(
padding: EdgeInsets.only(left: 20.0, right: 20.0),
child: TextFormField(
onChanged: (value) {
providerTest.updateAmount(value);
},
decoration: InputDecoration(
labelText: 'Amount',
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5)),
),
),
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 15,
),
cursorColor: Colors.black,
keyboardType: TextInputType.phone,
));
return Container(
child: Card(
child: Padding(
padding: EdgeInsets.only(top: 10, bottom: 5.0, left: 10.0, right: 10.0),
child: SingleChildScrollView(
child: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Text(
'Add Items',
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
),
items,
])))),
);
}
}
And at main.dart
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => ProviderTest(),
child: MaterialApp(
home: EditInvoice(),
),
);
}
}
More info about Provider Pattern here:
Provider Pattern

you can give callback to from child widget to parent widget to update data,
you can use inherited widget or provider

Related

Show widget when button is clicked (Dart, Flutter)

how can I show a widget (for example some more buttons) when a button is clicked.
FlatButton(
onPressed: () {
//render the new widgets
},
child: Icon(
Icons.close,
color: Colors.white,
),
));
This is the parent class
class StopStream extends StatelessWidget
You can conditionally show / hide a widget(s) with a help of a variable.
You need a StatefulWidget to change the state of a widget i.e to dynamically show / hide (widgets).
Please see the following code, I use a bool showWidget to show or hide more FlatButton's in a Row :
import 'package:flutter/material.dart';
final Color darkBlue = const Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatefulWidget {
#override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
bool showWidget = false;
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
showWidget
? Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FlatButton(
onPressed: () {},
child: const Icon(Icons.ac_unit),
),
FlatButton(
onPressed: () {},
child: const Icon(Icons.accessible),
),
FlatButton(
onPressed: () {},
child: const Icon(Icons.backpack),
),
FlatButton(
onPressed: () {},
child: const Icon(Icons.cached),
),
],
)
: Container(),
FlatButton(
onPressed: () {
setState(() {
showWidget = !showWidget;
});
},
child: const Icon(
Icons.close,
color: Colors.white,
),
),
],
);
}
}
Have a state variable (either in State or in something like Provider or Riverpod) that will be toggled by your onPressed: callback. Then allow that variable to control whether or not the widget in question is shown or omitted from the widget tree.
You can use a bool variable Forexample in my case isSwitched and set its value to false. When the user clicks on the button, set its value to true and use conditional operator to show more widgets as follows:
class CoverScreen extends StatefulWidget {
#override
_CoverScreenState createState() => _CoverScreenState();
}
class _CoverScreenState extends State<CoverScreen> {
bool isSwitched = false;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
toolbarHeight: 70,
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
child: Text('WELCOME'),
),
],
)),
body: Padding(
padding: const EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(children: <Widget>[
Container(
padding: const EdgeInsets.all(15),
child: Text(
'COVER LETTER:',
style: TextStyle(
color: Colors.teal,
fontSize: 25,
fontWeight: FontWeight.w500),
)),
Container(
child: Switch(
value: isSwitched,
onChanged: (value) {
setState(() {
isSwitched = value;
print(isSwitched);
});
},
activeTrackColor: Colors.teal,
activeColor: Colors.white,
)),
]),
Column(children: <Widget>[
isSwitched
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(10),
child: Text(
'NAME:',
style: TextStyle(
color: Colors.teal,
fontSize: 20,
fontWeight: FontWeight.w500),
)),
Container(
child: TextField(
decoration: new InputDecoration(
contentPadding:
const EdgeInsets.all(20.0),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.teal, width: 2.0),
),
hintText: 'Enter NAME'),
),
),
])
: Container(),
])
])),
);
}
}
The output for the above code is as follows:
Before button click
After Button click

Flutter: is there any possibility to send the button value to the text field?

I am Writing a small quiz game, in which I am pressing the button and these buttons are going to the empty text fields, I don't know how to send the text of the button to the text fields.
here is my code :
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: NinjaCard()));
class NinjaCard extends StatefulWidget {
#override
_NinjaCardState createState() => _NinjaCardState();
}
class _NinjaCardState extends State<NinjaCard> {
String result = "";
String shaka = "";
var text;
String str;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(title: Text('Animals'), backgroundColor: Colors.green),
body: Padding(
padding: EdgeInsets.all(15),
child: Column(
children: <Widget>[
Center(
child: Image.asset('lib/photo-1495594059084-33752639b9c3.jpg'),
),
SizedBox(width: 10, height: 10),
Row(children: <Widget>[
Container(
color: Colors.grey,
width: 40.0,
child: Text('$result', style: TextStyle(fontSize: 10.0, height: 2.0, color: Colors.black)),
),
SizedBox(width: 10),
Container(
color: Colors.grey,
width: 40.0,
child: Text('$shaka', style: TextStyle(fontSize: 10.0, height: 2.0, color: Colors.black)),
),
SizedBox(width: 15),
Row(
children: <Widget>[
SizedBox(
width: 50,
child: RaisedButton(
onPressed: () {},
color: Colors.green,
splashColor: Colors.red,
child: Text('S', style: TextStyle(backgroundColor: Colors.green, fontSize: 20, color: Colors.white)),
),
),
SizedBox(width: 15),
SizedBox(
width: 50,
child: RaisedButton(
onPressed: () {},
color: Colors.green,
splashColor: Colors.red,
child: Text('T', style: TextStyle(backgroundColor: Colors.green, fontSize: 20, color: Colors.white)),
),
),
SizedBox(width: 15),
],
),
]),
],
),
),
);
}
}
In a simple case, I would go with a stateful widget and array of letters. Of course, it could be created and sized dynamically, below I only explain the basic idea with some simplifications (no duplicate checks, no shuffling):
import 'package:flutter/material.dart';
void main() => runApp(App());
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'App',
home: GuessTheWordWidget(),
);
}
}
class GuessTheWordWidget extends StatefulWidget {
#override
_GuessTheWordWidgetState createState() => _GuessTheWordWidgetState();
}
class _GuessTheWordWidgetState extends State<GuessTheWordWidget> {
String _word = 'Goldfish';
List<String> _input = List.generate(8, (_) => '');
int _position = 0;
void _press(int rune) {
setState(() {
if (_position < _input.length) {
print('Position ${_position}, rune: ${String.fromCharCode(rune)}');
_input[_position++] = String.fromCharCode(rune);
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('App'),
),
body: Center(
child: Column(children: <Widget>[
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: _input
.map((letter) => Container(
margin: const EdgeInsets.all(15.0),
padding: const EdgeInsets.all(3.0),
decoration: BoxDecoration(
border: Border.all(color: Colors.blueAccent)),
child: Text(letter),
))
.toList())),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: _word.runes
.map((rune) => RaisedButton(
onPressed: () => _press(rune),
child: Text(String.fromCharCode(rune),
style: TextStyle(fontSize: 20)),
))
.toList())),
])),
);
}
}
Go play with this code at DartPad: https://dartpad.dev/69bae58772305c74f1688193076ecaef!

Listview with Checkbox using StatefulWidget(setState)

I am trying to develop an app in flutter, that has topics that the user can select and check box state will change when i scroll on listview check box state will not collapse and finally user give the submit the value are will bring out.i tried i am not able do that.
the error message shows:
The method 'setState' isn't defined for the class 'ItemDepletionList'.
Try correcting the name to the name of an existing method, or defining a method named 'setState'
class ItemDepletion extends StatefulWidget {
#override
_GetShaftsState createState() => _GetShaftsState();
}
class _GetShaftsState extends State<ItemDepletion> {
ItemDepletionBloc _bloc;
String json =
'{"RECORD_ID": "0", "REQTYPE": "ITEMDEPELTION", "CLINIC_ID": "1012"}';
#override
void initState() {
super.initState();
_bloc = ItemDepletionBloc(json);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0.0,
automaticallyImplyLeading: false,
title: Text('Chucky Categories',
style: TextStyle(color: Colors.white, fontSize: 20)),
backgroundColor: Color(0xFF333333),
),
backgroundColor: Color(0xFF333333),
body: RefreshIndicator(
onRefresh: () => _bloc.fetchCategories(json),
child: StreamBuilder<Response<List<Idepeltion>>>(
stream: _bloc.chuckListStream,
builder: (context, snapshot) {
if (snapshot.hasData) {
switch (snapshot.data.status) {
case Status.LOADING:
return Loading(loadingMessage: snapshot.data.message);
break;
case Status.COMPLETED:
return ItemDepletionList(
itemdepletionlst: snapshot.data.data);
break;
case Status.ERROR:
return Error(
errorMessage: snapshot.data.message,
onRetryPressed: () => _bloc.fetchCategories(json),
);
break;
}
}
return Container();
},
),
),
);
}
#override
void dispose() {
_bloc.dispose();
super.dispose();
}
}
class ItemDepletionList extends StatelessWidget {
// final Itemdepeltion categoryList;
final List<Idepeltion> itemdepletionlst;
const ItemDepletionList({Key key, this.itemdepletionlst}) : super(key: key);
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new Myappbar(title: new Text("Home Page")),
body: Column(children: [
Expanded(
child: ListView.builder(
itemCount: itemdepletionlst.length,
itemBuilder: (context, index) {
return ListTile(
title: new Container(
child: Row(
children: <Widget>[
new Checkbox(
value: itemdepletionlst[index].isCheck,
onChanged: (bool value) {
setState(() {
itemdepletionlst[index].isCheck = value;
});
}),
new Expanded(
child: new Container(
padding: new EdgeInsets.only(left: 8.0, right: 8.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
new Text(
'${itemdepletionlst[index].itemName}',
style: new TextStyle(
color: Colors.black,
fontWeight: FontWeight.w600,
fontSize: 16.0,
),
),
new Text(
'${itemdepletionlst[index].category}',
style: new TextStyle(color: Colors.grey),
),
],
),
),
),
new Expanded(
child: GestureDetector(
onTap: () {
selectedItem(
context, itemdepletionlst[index].suggQtyUnit);
},
child: new Container(
padding: new EdgeInsets.only(left: 8.0, right: 8.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
new Text(
'${itemdepletionlst[index].suggReorderQty} ${itemdepletionlst[index].suggQtyUnit}',
style: new TextStyle(
color: Colors.black,
fontWeight: FontWeight.w600,
fontSize: 16.0,
),
),
new Text(
'${itemdepletionlst[index].manuf}',
style: new TextStyle(color: Colors.grey),
),
],
),
),
)),
],
)));
},
),
),
RaisedButton(
// onPressed: getCheckboxItems,
textColor: Colors.white,
padding: const EdgeInsets.all(0.0),
child: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: <Color>[
Color(0xFF09a3c8),
Color(0xFF39B9B4),
Color(0xFF0fb188),
],
),
),
padding: const EdgeInsets.all(10.0),
child: const Text('Submit',
style: TextStyle(fontSize: 20, color: Colors.white)),
),
),
])
);
}
}
Your ItemDepletionList class is stateless and You are trying to call setstate in it because of that you are getting that error. make it Stateful then it will work.
replace Following line.
class ItemDepletionList extends StatelessWidget {
With this
class ItemDepletionList extends StatefulWidget {
final List<Idepeltion> itemdepletionlst;
ItemDepletionList({this.itemdepletionlst});
#override
_ItemDepletionListState createState() => _ItemDepletionListState();
}
class _ItemDepletionListState extends State<ItemDepletionList> {
And now to access itemdepletionlst you have use widget.
widget.itemdepletionlst

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:

Executing Navigator.pop() when key pad is visible results in render flex error

I have noticed creating forms with flutter. That if there is Scaffold with a text field focused i.e the key pad visible if one presses the back button.
Navigator.pop();
This results in an render flex error.
I have tried wrapping the child in the single child scroll view components also tried setting the resize to avoid bottom padding property to true.
I still get the error.
Has anyone else experienced this ?
if so what is the solution and cause of the error ?
EDIT:
import 'package:flutter/material.dart';
class SettingsScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(
title: Text(
"Settings",
style: TextStyle(
color: primaryColor,
fontFamily: titleFontStyle
),
),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: primaryColor),
onPressed: () {
Navigator.of(context).pop();
},
),
centerTitle: true,
backgroundColor: Colors.white,
elevation: 0.0,
),
backgroundColor: Colors.white,
body: Container(
// width: MediaQuery.of(context).size.width - 10.0,
// height: MediaQuery.of(context).size.height,
// padding: EdgeInsets.fromLTRB(20.0, 60.0, 20.0, 0.0),
child: SettingsForm(),
),
);
}
}
class SettingsForm extends StatefulWidget {
#override
_SettingsFormState createState() => _SettingsFormState();
}
class _SettingsFormState extends State<SettingsForm> {
final _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.only(top: 50.0),
child: ListView(
shrinkWrap: true,
padding: EdgeInsets.only(left: 24.0, right: 24.0),
children: <Widget>[
TextField(
autofocus: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Username',
),
),
SizedBox(height: 8.0),
RaisedButton(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 40.0),
textColor: Colors.white,
color: primaryColor,
child: Text(
'Update',
style: TextStyle(
color: Colors.white
),
),
onPressed: () {},
),
],
),
),
);
}
}
I have tried that, and it works fine. The keyboard layout will close when you press back button and navigate you to previous page.
Here is my 2 dart files below:
main.dart (From which I navigating through)
import 'settings.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: new HomeScreen()
);
}
}
class HomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Title"),
),
body: new Center(child: new Text("Click Mee")),
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.add),
backgroundColor: Colors.orange,
onPressed: () {
print("Clicked");
Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new SettingsForm()),
);
},
),
);
}
}
settings.dart (your provided code on next screen)
class SettingsForm extends StatefulWidget {
SettingsForm();
#override
_SettingsFormState createState() => _SettingsFormState();
}
class _SettingsFormState extends State<SettingsForm> {
final _formKey = GlobalKey<FormState>();
Color primaryColor = const Color.fromRGBO(3, 155, 226, 1);
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(
title: Text(
"Settings",
style: TextStyle(
color: primaryColor
),
),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: primaryColor),
onPressed: () {
FocusScope.of(context).unfocus();
Navigator.of(context).pop();
print("yes");
},
),
centerTitle: true,
backgroundColor: Colors.white,
elevation: 0.0,
),
backgroundColor: Colors.white,
body: Container(
// width: MediaQuery.of(context).size.width - 10.0,
// height: MediaQuery.of(context).size.height,
// padding: EdgeInsets.fromLTRB(20.0, 60.0, 20.0, 0.0),
child: Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.only(top: 50.0),
child: ListView(
shrinkWrap: true,
padding: EdgeInsets.only(left: 24.0, right: 24.0),
children: <Widget>[
TextField(
autofocus: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Username',
),
),
SizedBox(height: 8.0),
RaisedButton(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 40.0),
textColor: Colors.white,
color: primaryColor,
child: Text(
'Update',
style: TextStyle(
color: Colors.white
),
),
onPressed: () {},
),
],
),
),
),
),
);
}
}
The issue was that when I navigate back to the previous component. It was the previous component that overflowed.
I had used Column in the said component.
Converting it into ListView solved the error.