Flutter - how to add rows with a click on a button - flutter

I want the 6 ball row(plz refer to this image) to be added when I click the '+Add Rows' button, but I've got 1 problem which is that I'm not sure that it has a Listview like I coded.
Please help me to complete 'void addRow()' to add a row with a click on a button.
And could you give me some tips on how to get a new row with completely different random numbers from other rows?
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'dart:math';
import 'package:barcode_scan/barcode_scan.dart';
void main() => runApp(
MaterialApp(
home: BallPage()
),
);
class BallPage extends StatefulWidget {
#override
_BallPageState createState() => _BallPageState();
}
class _BallPageState extends State<BallPage>{
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
drawer: new Drawer(),
appBar: AppBar(
title: Text(
'Magic 6 balls'),
backgroundColor: Colors.black,
actions: <Widget>[
new IconButton(
icon: new Icon(MdiIcons.squareInc),
color: Colors.white,
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => SecondRoute())
);
},
),
],
),
body: Number(),
);
}
}
class SecondRoute extends StatefulWidget {
#override
_SecondRouteState createState() {
return new _SecondRouteState();
}
}
class _SecondRouteState extends State<SecondRoute>{
String result ="Hey there!";
Future _scanQR() async {
try{
String qrResult = await BarcodeScanner.scan();
setState(() {
result = qrResult;
});
} on PlatformException catch (ex) {
if (ex.code == BarcodeScanner.CameraAccessDenied){
setState(() {
result = "Camera permission was denied";
});
} else {
setState(() {
result = "Unknown Error $ex";
});
}
} on FormatException {
setState(() {
result = "You pressed the black button before scanning anything";
});
}catch (ex) {
setState(() {
result = "Unknown Error $ex";
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('QR Code Scan'),
),
body: Center(
child: Text(
result,
style: new TextStyle(fontSize: 20.0),
),
),
floatingActionButton: FloatingActionButton.extended(
onPressed: _scanQR,
label: Text('Scan'),
icon: Icon(Icons.camera_alt),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
}
class Number extends StatefulWidget {
#override
_NumberState createState() => _NumberState();
}
class _NumberState extends State<Number> {
int ball1 = 1;
int ball2 = 1;
int ball3 = 1;
int ball4 = 1;
int ball5 = 1;
int ball6 = 1;
void randomNumbers() {
setState(() {
ball1 = Random().nextInt(49) + 1;
ball2 = Random().nextInt(49) + 1;
ball3 = Random().nextInt(49) + 1;
ball4 = Random().nextInt(49) + 1;
ball5 = Random().nextInt(49) + 1;
ball6 = Random().nextInt(49) + 1;
});
}
void addRows(){
setState(() {
});
}
void removeRows(){
setState(() {
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: ListView(
children: <Widget>[
SizedBox(height: 100.0),
Center(
child: Text('Winners Number')
),
SizedBox(height: 16.0),
buildForm(),
SizedBox(height: 16.0),
RaisedButton.icon(
icon: Icon(Icons.add),
label: Text('Add Rows'),
onPressed: () {
addRows();
},
),
],
),
),
],
),
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () {
randomNumbers();
},
label: Text(
'Click Here!'),
icon: Icon(
Icons.loop),
backgroundColor: Colors.black,
),
);
}
Widget buildForm() {
List<Widget> list = new List();
for (var index = 0; index < 1; index++) {
list.add(Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
height: 60,
width: 60,
child: Center
(
child: Text(
'$ball1',
style: TextStyle(
fontSize: 20.0,
),
),
),
decoration: BoxDecoration(
color: Colors.yellow,
shape: BoxShape.circle,
),
),
Container(
height: 60,
width: 60,
child: Center
(
child: Text(
'$ball2',
style: TextStyle(
fontSize: 20.0,
),
),
),
decoration: BoxDecoration(
color: Colors.yellow,
shape: BoxShape.circle,
),
),
Container(
height: 60,
width: 60,
child: Center
(
child: Text(
'$ball3',
style: TextStyle(
fontSize: 20.0,
),
),
),
decoration: BoxDecoration(
color: Colors.yellow,
shape: BoxShape.circle,
),
),
Container(
height: 60,
width: 60,
child: Center
(
child: Text(
'$ball4',
style: TextStyle(
fontSize: 20.0,
),
),
),
decoration: BoxDecoration(
color: Colors.yellow,
shape: BoxShape.circle,
),
),
Container(
height: 60,
width: 60,
child: Center
(
child: Text(
'$ball5',
style: TextStyle(
fontSize: 20.0,
),
),
),
decoration: BoxDecoration(
color: Colors.yellow,
shape: BoxShape.circle,
),
),
Container(
height: 60,
width: 60,
child: Center
(
child: Text(
'$ball6',
style: TextStyle(
fontSize: 20.0,
color: Colors.white,
),
),
),
decoration: BoxDecoration(
color: Colors.black,
shape: BoxShape.circle,
),
),
],
));
list.add(
SizedBox(
height: 12.0,
));
}
return Column(
children: list);
}
}

What I would recommend to do is, have the rows always there but just hide them with Visibility widget.
Add an int counter variable and increment it on each click on addRow.
Then wrap your ball widgets around with visibility and do something like that:
Pseudo-code
Visibilty(
visible: counter == 1,
child: BallWidget(),
)
... and so on for all the other ball widgets.
Hope it helps.

Related

How to get title & url of the news displayed in the current card?

I've been showing news titles & images in a tinder-like UI in flutter.
Here's main.dart:
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Swoosh',
theme: ThemeData(primarySwatch: Colors.blue),
home: ChangeNotifierProvider(
create: (_) => DataFetched(),
child: SwipeFeedPage(),
));
}
}
Here's swipe_feed_page.dart:
class SwipeFeedPage extends StatefulWidget {
#override
_SwipeFeedPageState createState() => _SwipeFeedPageState();
}
class _SwipeFeedPageState extends State<SwipeFeedPage> {
bool showAlignmentCards = true;
bool done = false;
List getList = [];
String _newsText = '';
String _newsUrl = '';
String _dateToday = DateFormat('yyyy-MM-dd').format(DateTime.now());
String _dateYesterday = DateFormat('yyyy-MM-dd')
.format(DateTime.now().subtract(Duration(days: 1)));
Future fetchData() async {
http.Response response;
response = await http.get(Uri.parse(
"https://newsapi.org/v2/everything?q=india&from=$_dateYesterday&to=$_dateToday&sortBy=popularity&language=en&apiKey=xxxxxxxxx"));
final data = await json.decode(response.body);
if (response.statusCode == 200) {
done = true;
getList = data["articles"];
setState(() {
for (var i = 0; i < getList.length; i++) {
Provider.of<DataFetched>(context, listen: false)
.title
.add(getList[i]["title"]);
Provider.of<DataFetched>(context, listen: false)
.imageUrl
.add(getList[i]["urlToImage"]);
Provider.of<DataFetched>(context, listen: false)
.url
.add(getList[i]["url"]);
}
});
}
}
#override
void initState() {
super.initState();
done = false;
fetchData();
}
#override
Widget build(BuildContext context) {
if (done) {
return Scaffold(
appBar: AppBar(
elevation: 0.0,
centerTitle: true,
backgroundColor: Colors.white,
leading: IconButton(
onPressed: () {}, icon: Icon(Icons.settings, color: Colors.grey)),
actions: <Widget>[
IconButton(
onPressed: () {},
icon: Icon(Icons.question_answer, color: Colors.grey)),
],
),
backgroundColor: Colors.white,
body: Column(
children: <Widget>[
showAlignmentCards
? CardsSectionAlignment(context)
: CardsSectionDraggable(),
buttonsRow()
],
),
);
} else {
return Center(child: CircularProgressIndicator());
}
}
Widget buttonsRow() {
for (int i = 0; i < getList.length; i++) {
_newsText = Provider.of<DataFetched>(context, listen: false).title[i];
_newsUrl = Provider.of<DataFetched>(context, listen: false).url[i];
}
return Container(
margin: EdgeInsets.symmetric(vertical: 48.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
FloatingActionButton(
mini: true,
onPressed: () {},
backgroundColor: Colors.white,
child: Icon(Icons.loop, color: Colors.yellow),
),
Padding(padding: EdgeInsets.only(right: 8.0)),
FloatingActionButton(
onPressed: () async {
if (await canLaunchUrl(Uri.parse(_newsUrl))) {
await launch(_newsUrl,
forceWebView: true, enableJavaScript: true);
}
},
backgroundColor: Colors.white,
child: Icon(Icons.open_in_browser, color: Colors.red),
),
Padding(padding: EdgeInsets.only(right: 8.0)),
FloatingActionButton(
onPressed: () {
Share.share(_newsText +
': ' +
_newsUrl);
},
backgroundColor: Colors.white,
child: Icon(Icons.share, color: Colors.green),
),
Padding(padding: EdgeInsets.only(right: 8.0)),
FloatingActionButton(
mini: true,
onPressed: () {},
backgroundColor: Colors.white,
child: Icon(Icons.star, color: Colors.blue),
),
],
),
);
}
}
Here's profile_card_alignment:
class ProfileCardAlignment extends StatelessWidget {
final int cardNum;
ProfileCardAlignment(this.cardNum);
#override
Widget build(BuildContext context) {
final title = Provider.of<DataFetched>(context).title.length > 0
? Provider.of<DataFetched>(context).title[cardNum]
: "Please Swipe";
final imageUrl = Provider.of<DataFetched>(context).imageUrl.length > 0
? Provider.of<DataFetched>(context).imageUrl[cardNum]
: "https://i.picsum.photos/id/1021/2048/1206.jpg?hmac=fqT2NWHx783Pily1V_39ug_GFH1A4GlbmOMu8NWB3Ts";
return Card(
child: Stack(
children: <Widget>[
SizedBox.expand(
child: Material(
borderRadius: BorderRadius.circular(10.0),
child: Image.network(imageUrl, fit: BoxFit.cover),
),
),
SizedBox.expand(
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.transparent, Colors.black54],
begin: Alignment.center,
end: Alignment.bottomCenter)),
),
),
Align(
alignment: Alignment.bottomLeft,
child: Container(
padding: EdgeInsets.symmetric(vertical: 16.0, horizontal: 16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(title,
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.w700)),
Padding(padding: EdgeInsets.only(bottom: 8.0)),
// Text('A short description.',
// textAlign: TextAlign.start,
// style: TextStyle(color: Colors.white)),
],
)),
)
],
),
);
}
}
In the swipe_feed_page.dart, I am trying to assign the value of _newsText & _newsUrl but instead of getting assigned the value of the current card/news, the last value in the list is getting assigned to it. How can I make sure that the value of current card/news should get assigned to them?

Hello, I want to show the padding part at the bottom of my code on the screen with a delay of 10 seconds. How can I do it?

I want to show the padding part at the bottom of my code on the screen with a delay of 10 seconds. How can I do it?
My Code :
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_clipboard_manager/flutter_clipboard_manager.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'URL Shortener',
theme: ThemeData(
primarySwatch: Colors.purple,
),
home: StartPage(),
);
}
}
class StartPage extends StatefulWidget {
#override
_StartPageState createState() => _StartPageState();
}
class _StartPageState extends State<StartPage> {
bool visibilityTag = false;
void _changed(bool visibility, String field) {
setState(() {
if (field == "tag") {
visibilityTag = visibility;
}
});
}
final GlobalKey<ScaffoldState> _globalKey = GlobalKey<ScaffoldState>();
String shortUrl = "";
String value = "";
String buttonText = "COPY!";
bool isChanged = true;
TextEditingController urlcontroller = TextEditingController();
getData() async {
var url = 'https://api.shrtco.de/v2/shorten?url=${urlcontroller.text}';
var response = await http.get(url);
var result = jsonDecode(response.body);
if (result['ok']) {
setState(() {
shortUrl = result['result']['short_link'];
});
} else {
print(response);
}
}
copy(String url) {
FlutterClipboardManager.copyToClipBoard(url).then((value) {});
}
buildRow(String data, bool original) {
return SingleChildScrollView(
child: original
? Container(
alignment: Alignment.center,
child: Text(
data,
))
: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
data,
),
ElevatedButton(
child: Text(buttonText),
style: ElevatedButton.styleFrom(
primary: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
minimumSize: Size(300, 40),
),
onPressed: () {
copy(shortUrl);
setState(() {
if (isChanged == true) {
buttonText = "COPIED!";
}
});
},
),
],
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[300],
body: ListView(
children: [
SvgPicture.asset(
'assets/logo.svg',
),
SvgPicture.asset(
'assets/illustration.svg',
),
Center(
child: Text(
"Let's get started!",
style: TextStyle(
fontSize: 20,
color: Color.fromRGBO(53, 50, 62, 10),
fontWeight: FontWeight.bold),
),
),
Center(
child: SizedBox(
width: 200,
height: 60,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Paste your first link into the field to shorten it",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
color: Color.fromRGBO(76, 74, 85, 10),
fontWeight: FontWeight.bold)),
),
),
),
SizedBox(
height: 130,
child: Stack(
alignment: Alignment.center,
children: [
Container(
alignment: Alignment.centerRight,
color: Color.fromRGBO(59, 48, 84, 1),
child: SvgPicture.asset(
'assets/shape.svg',
color: Color.fromRGBO(75, 63, 107, 1),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 300,
height: 40,
child: TextField(
onChanged: (text) {
value = "URL : " + text;
},
controller: urlcontroller,
textAlign: TextAlign.center,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
border: OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(10.0),
),
borderSide: BorderSide(
width: 0,
style: BorderStyle.none,
),
),
fillColor: Colors.white,
filled: true,
hintText: 'Shorten a link here ...'),
),
),
SizedBox(
height: 10,
),
SizedBox(
width: 300,
child: ElevatedButton(
onPressed: getData,
style: ElevatedButton.styleFrom(
primary: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
minimumSize: Size(60, 40),
),
child: Text('SHORTEN IT!'),
),
),
],
),
],
),
),
Padding(
padding: const EdgeInsets.all(13.0),
child: Container(
color: Colors.white,
width: double.infinity,
child: Column(
children: [
SizedBox(
height: 10,
),
buildRow(value, true),
buildRow(shortUrl, false),
],
),
),
)
],
),
);
}
}
Hello, I want to show the padding part at the bottom of my code on the screen with a delay of 10 seconds. How can I do it?
Hello, I want to show the padding part at the bottom of my code on the screen with a delay of 10 seconds. How can I do it?
Hello, I want to show the padding part at the bottom of my code on the screen with a delay of 10 seconds. How can I do it?Hello, I want to show the padding part at the bottom of my code on the screen with a delay of 10 seconds. How can I do it?
On State create a bool like
bool showCopyButton = false;
Change to true at
SizedBox(
width: 300,
child: ElevatedButton(
onPressed: ()async {
print("Button Click");
await getData();
setState(() {
showCopyButton = true;
});
},
style: ElevatedButton.styleFrom(
primary: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
minimumSize: Size(60, 40),
),
child: Text('SHORTEN IT!'),
),
),
And wrap with Visibility Like
Visibility(
visible: showCopyButton,
child: Padding(
padding: const EdgeInsets.all(13.0),
child: Container(
color: Colors.white,
width: double.infinity,
child: Column(
children: [
SizedBox(
height: 10,
),
buildRow("Text ", true),
buildRow("asdad", false),
],
),
),
),
)
or you can just if like
if (showCopyButton)
Padding(
padding: const EdgeInsets.all(13.0),
child: Container(
color: Colors.white,
width: double.infinity,
child: Column(
children: [
SizedBox(
height: 10,
),
buildRow("Text ", true),
buildRow("asdad", false),
],
),
),
),
Btw you need to use await before making it true.
Hope this helps:
import 'package:flutter/material.dart';
class Screen extends StatefulWidget {
#override
_ScreenState createState() => _ScreenState();
}
class _ScreenState extends State<Screen> {
bool _paddingVisible = false;
#override
void initState() {
super.initState();
Future.delayed(const Duration(seconds: 10), () {
// Check if mounted == true, because the screen might closed
// before 10 seconds pass
if (mounted) {
// Setting padding visibility to true after 10 seconds
setState(() {
_paddingVisible = true;
});
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
children: [
// All your widgets
// When _paddingVisible becomes true it will be displayed
if (_paddingVisible) SizedBox(height: 10),
],
),
);
}
}

Flutter how to create Multi Card and select a color

I am new in flutter, I want to create multi card with some option and select a option then change color. In my code when click one option number but all of color same change, please help to fix it.
link all code
[https://github.com/gunartha/Multi-Question-and-multi-selection-with-color-option]
This is happening because you are using same color for all the 15 questions.
To have each of the 15 card behave independently you need List of size 15. Check the changes made by me below. This should fix your problem.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Click Color Card',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final kSecondaryColor = Color(0xFF8B94BC);
final kPrimaryColor = Color(0xFF748BF5);
final kGreenColor = Color(0xFFAAF39C);
final kRedColor = Color(0xFFF7BCBD);
final kYellowColor = Color(0xFFF0EE8C);
final kGrayColor = Color(0xFFD8D5D5);
final kBlackColor = Color(0xFF101010);
List<Color> colorYes = List.filled(15, Color(0xFFD8D5D5));
List<Color> colorNo = List.filled(15, Color(0xFFD8D5D5));
List<Color> colorNA = List.filled(15, Color(0xFFD8D5D5));
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Click Multi color"),
),
body: ListView.builder(
itemCount: 15,
itemBuilder: (context, index) {
return new Center(
child: Container(
width: MediaQuery.of(context).size.width * 0.95,
height: 250,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
),
child: Card(
child: Column(
children: [
SizedBox(
height: 20,
),
Text("Question $index"),
SizedBox(
height: 10,
),
InkWell(
//yes
onTap: () {
setState(() {
colorYes[index] = kGreenColor;
colorNo[index] = kGrayColor;
colorNA[index] = kGrayColor;
});
},
child: Container(
width: 200,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: colorYes[index],
),
child: Container(
child: Center(
child: Text(
"Yes",
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
textAlign: TextAlign.center,
),
),
),
),
),
SizedBox(
height: 10,
),
InkWell(
onTap: () {
setState(() {
colorYes[index] = kGrayColor;
colorNo[index] = kRedColor;
colorNA[index] = kGrayColor;
});
},
child: Container(
width: 200,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: colorNo[index],
),
child: Container(
child: Center(
child: Text(
"No",
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
textAlign: TextAlign.center,
),
),
),
),
),
SizedBox(
height: 10,
),
InkWell(
onTap: () {
setState(() {
colorYes[index] = kGrayColor;
colorNo[index] = kGrayColor;
colorNA[index] = kYellowColor;
});
},
child: Container(
width: 200,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: colorNA[index],
),
child: Container(
child: Center(
child: Text(
"N/A",
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
textAlign: TextAlign.center,
),
),
),
),
),
SizedBox(
height: 10,
),
],
),
),
),
);
}));
}
}
You don't need to put extra effort, Simply create question answer bean and store data in that. when you change state then you find same data in bean and you can render card color on specific card.
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Click Color Card',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final kSecondaryColor = Color(0xFF8B94BC);
final kPrimaryColor = Color(0xFF748BF5);
final kGreenColor = Color(0xFFAAF39C);
final kRedColor = Color(0xFFF7BCBD);
final kYellowColor = Color(0xFFF0EE8C);
final kGrayColor = Color(0xFFD8D5D5);
final kBlackColor = Color(0xFF101010);
Color colorYes = Color(0xFFD8D5D5);
Color colorNo = Color(0xFFD8D5D5);
Color colorNA = Color(0xFFD8D5D5);
List<QueAnsBean> data = [];
#override
void initState() {
super.initState();
generateBean();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Click Multi color"),
),
body: ListView.builder(
itemCount: 15,
itemBuilder: (context, index) {
QueAnsBean item = data[index];
return new Center(
child: Container(
width: MediaQuery.of(context).size.width * 0.95,
height: 250,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
),
child: Card(
child: Column(
children: [
SizedBox(
height: 20,
),
Text("${item._que}"),
SizedBox(
height: 10,
),
InkWell(
//yes
onTap: () {
item._answer = "1";
setState(() {});
},
child: Container(
width: 200,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: item._answer == "1"
? kGreenColor
: kGrayColor,
),
child: Container(
child: Center(
child: Text(
"Yes",
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
textAlign: TextAlign.center,
),
),
),
),
),
SizedBox(
height: 10,
),
InkWell(
onTap: () {
item._answer = "2";
setState(() {});
},
child: Container(
width: 200,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color:
item._answer == "2" ? kRedColor : kGrayColor,
),
child: Container(
child: Center(
child: Text(
"No",
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
textAlign: TextAlign.center,
),
),
),
),
),
SizedBox(
height: 10,
),
InkWell(
onTap: () {
item._answer = "3";
setState(() {});
},
child: Container(
width: 200,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: item._answer == "3"
? kYellowColor
: kGrayColor,
),
child: Container(
child: Center(
child: Text(
"N/A",
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
textAlign: TextAlign.center,
),
),
),
),
),
SizedBox(
height: 10,
),
],
),
),
),
);
}));
}
void generateBean() {
for (int i = 0; i < 15; i++) {
data.add(QueAnsBean(que: "Question - $i", answer: ""));
}
}
}
class QueAnsBean {
String? _que;
String? _answer;
String? get que => _que;
String? get answer => _answer;
QueAnsBean({String? que, String? answer}) {
_que = que;
_answer = answer;
}
QueAnsBean.fromJson(dynamic json) {
_que = json["que"];
_answer = json["Answer"];
}
Map<String, dynamic> toJson() {
var map = <String, dynamic>{};
map["que"] = _que;
map["Answer"] = _answer;
return map;
}
}

setState() not working properly in flutter

I have a question palette in the flutter screen, where a user taps on the question number that question is shown, and a next button to display the next question.
If I am traversing between the questions using the question palette it's working fine but when I click next button, it does not turn the question number on the palette to green(I want that question number to get green) and also it does not return the next question but the loop iterates. As after I press the button for some time, it says that there are no next questions as I have set this message when the loop ends.
Here is my code:
class quizpage extends StatefulWidget{
var questions,surveyid;
quizpage(this.questions,this.surveyid);
//quizpage({Key key, #required this.questions}) : super(key : key);
#override
_quizpageState createState() => _quizpageState(questions,surveyid);
}
class _quizpageState extends State<quizpage> with SingleTickerProviderStateMixin {
var questions,surveyid;
_quizpageState(this.questions,this.surveyid);
int i = 0;
int flag = 0;
int counter = 0;
int length;
Map<String, Color> btncolor = {
"1" : Colors.grey,
"2" : Colors.grey,
"3" : Colors.grey,
"4" : Colors.grey,
"5" : Colors.grey,
"6" : Colors.grey,
"7" : Colors.grey,
"8" : Colors.grey,
"9" : Colors.grey,
};
final answercontroller = TextEditingController();
#override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitDown, DeviceOrientation.portraitUp
]);
SizeConfig().init(context);
// TODO: implement build
return Scaffold(
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SizedBox(
height: 600,
child: Column(
children: <Widget>[
Expanded(
flex: 1,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Numberofquestion()
],
),
),
Expanded(
flex: 4,
child: Center(
child: Container(
width: 400,
height: 400,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
width: 250,
child: Material(
elevation: 5,
color: Colors.deepOrange,
borderRadius: BorderRadius.all(
Radius.circular(10.0)),
child: TextField(
enabled: false,
maxLines: 6,
decoration: InputDecoration(
fillColor: Colors.white,
filled: true,
hintText: questions[i]
),
style: TextStyle(
fontSize: 20,
color: Colors.black
),
),
),
)
],
),
),
)
),
Expanded(
flex: 2,
child: Center(
child: Container(
width: 300,
height: 300,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
width: 250,
child: Material(
elevation: 2,
color: Colors.deepOrange,
borderRadius: BorderRadius.all(
Radius.circular(10.0)),
child: TextField(
controller: answercontroller,
maxLines: 1,
//enabled: false,
decoration: InputDecoration(
fillColor: Colors.white,
filled: true,
hintText: 'Answer'
),
style: TextStyle(
fontSize: 20,
color: Colors.black
),
),
),
),
]
)
)
)
),
Expanded(
flex: 2,
child: Align(
alignment: Alignment.topCenter,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(onPressed: SkipQuestion,
color: Colors.deepOrange,
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0))),
child: Text('Skip',
style: TextStyle(
fontSize: 20
),
),
),
RaisedButton(onPressed: NextQuestion,
color: Colors.green,
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0))),
child: Text('Next',
style: TextStyle(
fontSize: 20
),
),
),
],
),
],
),
)
)
],
),
),
),
),
);
}
#override
void setState(fn) {
// TODO: implement setState
super.setState(fn);
if(btncolor[(i+1).toString()] == Colors.deepOrange){
btncolor[(i+1).toString()] = Colors.purple;
flag = 1;
}
else if(btncolor[(i+1).toString()] == Colors.green){
btncolor[(i+1).toString()] = Colors.purple;
flag = 2;
}
else{
btncolor[(i+1).toString()] = Colors.purple;
}
}
void NextQuestion() async {
if(answercontroller.text.length == 0){
await showDialog(
context: context,
builder: (context) => new AlertDialog(
title: new Text('Alert'),
content: Text(
'Please enter an answer.'),
actions: <Widget>[
new FlatButton(
onPressed: () {
Navigator.of(context, rootNavigator: true)
.pop(); // dismisses only the dialog and returns nothing
},
child: new Text('OK'),
),
],
),
);
}
else{
setState(() async {
if(i < (questions.length - 1)){
// ignore: unnecessary_statements
btncolor[(i+1).toString()] = Colors.green;
i++;
}
else{
await showDialog(
context: context,
builder: (context) => new AlertDialog(
title: new Text('Alert'),
content: Text(
'There are no next questions.'),
actions: <Widget>[
new FlatButton(
onPressed: () {
Navigator.of(context, rootNavigator: true)
.pop(); // dismisses only the dialog and returns nothing
},
child: new Text('OK'),
),
],
),
);
}
});
}
}
#override
void initState() {
SystemChrome.setEnabledSystemUIOverlays([]);
super.initState();
}
void SkipQuestion() {
setState(() {
if(i < (questions.length - 1)){
// ignore: unnecessary_statements
btncolor[(i+1).toString()] = Colors.deepOrange;
i++;
}
else{
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => resultpage(surveyid),
));
}
});
}
void ChooseQuestion() {
setState(() {
if(i < (questions.length)){
for(int k =0; k< (questions.length); k++){
if(k != i){
if(btncolor[(k+1).toString()] == Colors.purple){
if(flag == 1){
btncolor[(k+1).toString()] = Colors.red;
flag =0;
}
else if(flag == 2){
btncolor[(k+1).toString()] = Colors.green;
flag =0;
}
else{
btncolor[(k+1).toString()] = Colors.grey;
}
}
}
else{
if(btncolor[(k+1).toString()] == Colors.purple){
if(flag == 1){
btncolor[(k+1).toString()] = Colors.red;
}
else if(flag == 2){
btncolor[(k+1).toString()] = Colors.green;
flag =0;
}
else{
btncolor[(k+1).toString()] = Colors.grey;
}
}
}
}
//i++;
}
else{
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => resultpage(surveyid),
));
}
});
}
Widget Numberofquestion() {
if(questions.length == 9){
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
width: 40,
padding: EdgeInsets.all(5),
child: RaisedButton(onPressed: () {
i = 0;
ChooseQuestion();
},
color: btncolor["1"],
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0))),
child: Text("1",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20
),
),
),
),
Container(
width: 40,
padding: EdgeInsets.all(5),
child: RaisedButton(onPressed: () {
i = 1;
ChooseQuestion();
},
color: btncolor["2"],
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0))),
child: Text('2',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20
),
),
),
),
Container(
width: 40,
padding: EdgeInsets.all(5),
child: RaisedButton(onPressed: () {
i = 2;
ChooseQuestion();
},
color: btncolor["3"],
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0))),
child: Text('3',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20
),
),
),
),
Container(
width: 40,
padding: EdgeInsets.all(5),
child: RaisedButton(onPressed: () {
i = 3;
ChooseQuestion();
},
color: btncolor["4"],
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0))),
child: Text('4',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20
),
),
),
),
],
);
}
}
}
Here, questions is the array which stores the question.
When I am using the 'Skip' button, the setState works perfectly but when I am using 'Next' button the setState is not working.
Can someone help me with this please?
I'd say that you're manipulating the state in a wrong way
As docs refers:
#protected
void setState (VoidCallback fn)
The provided callback is immediately called synchronously. It must not return a future (the callback cannot be async), since then it would be unclear when the state was actually being set.
things to note:
don't call setState() inside initState()
don't call setState() in synchronous code inside build()
setState() should run synchronously so new updates happen atomically
hence, try not to mark setState() as async
You might see the link, hope it's useful
try this
#override
void setState(fn) {
if(btncolor[(i+1).toString()] == Colors.deepOrange){
btncolor[(i+1).toString()] = Colors.purple;
flag = 1;
}
else if(btncolor[(i+1).toString()] == Colors.green){
btncolor[(i+1).toString()] = Colors.purple;
flag = 2;
}
else{
btncolor[(i+1).toString()] = Colors.purple;
}
super.setState(fn);//move here
}

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: