Extract Future<Object> variables in Flutter? - flutter

I am currently creating a profile system, in which users can edit certain attributes. I can already GET any and all information that has previously been entered by the user, as well as updating each observation in the database. I am attempting to print the given values to the screen, so the user can see their previously saved input before choosing to change.
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
final _formKey = GlobalKey<FormState>();
StorageService storage = StorageService();
userInfo info = userInfo(0, 0,"","", "", "", "");
Future<userInfo> fetchUserInfo() async {
String jwt = await storage.readSecureData("jwt") as String;
Map<String, dynamic> map = Jwt.parseJwt(jwt);
String url = 'http://localhost:8087/getinfo/' + map["id"];
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
print(response.body);
// info = userInfo.fromJson(jsonDecode(response.body));
return userInfo.fromJson(jsonDecode(response.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load userInfo');
}
}
This is my GET request. It works perfectly and returns an userInfo object.
#override
Widget build(BuildContext context) {
userInfo info = userInfo(0, 0,"","", "", "", "");
final ButtonStyle style =
ElevatedButton.styleFrom(
primary: Colors.green,
fixedSize: Size(200, 50),
textStyle: const TextStyle(fontSize: 20),
);
return Padding(
padding: EdgeInsets.all(0),
child: ListView(
children: <Widget>[
Container(
height: 410,
margin: const EdgeInsets.fromLTRB(20, 20, 20, 20),
padding: const EdgeInsets.fromLTRB(20, 20, 20, 20),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.all(Radius.circular(18))
),
child: Column(
children: <Widget> [
const Text("Patient Details" , style: TextStyle(fontSize: 40, color: Colors.white)),
Row(
children: [
const Text("Medicare:" , style: TextStyle(fontSize: 30, height: 2, color: Colors.white)),
const Text("1234567891" , style: TextStyle(fontSize: 30, height: 2, color: Colors.black)),
]),
Row(
children: [
const Text("Home Address:" , style: TextStyle(fontSize: 30, height: 2, color: Colors.white)),
]),
Row(
children: [
Text(info.address , style: TextStyle(fontSize: 30, height: 2, color: Colors.black)),
]),
Row(
children: [
const Text("Mobile:" , style: TextStyle(fontSize: 30, height: 2, color: Colors.white)),
const Text("0447171002" , style: TextStyle(fontSize: 30, height: 2, color: Colors.black)),
]),
Container(
margin: const EdgeInsets.fromLTRB(0, 25, 0, 0),
child: ElevatedButton.icon(
style: style,
icon: const Icon(Icons.edit),
label: const Text('Edit Personal'),
onPressed: () async {
Navigator.push(
context, MaterialPageRoute(builder: (context) => const EditInfoApp()));
},
)
)]),
),
Container(
height: 470,
margin: const EdgeInsets.fromLTRB(20, 20, 20, 20),
padding: const EdgeInsets.fromLTRB(20, 20, 20, 20),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.all(Radius.circular(18))
),
child: Column(
children: <Widget> [
const Text("Health Information" , style: TextStyle(fontSize: 40, color: Colors.white)),
Row(
children: [
const Text("Health Status: " , style: TextStyle(fontSize: 30, height: 2, color: Colors.white)),
const Text("average" , style: TextStyle(fontSize: 30, height: 2, color: Colors.black)),
]),
Row(
children: [
const Text("Allergies:" , style: TextStyle(fontSize: 30, height: 2, color: Colors.white)),
]),
Row(
children: [
const Text("nuts, Peanuts, fish" , style: TextStyle(fontSize: 30, height: 2, color: Colors.black)),
]),
Row(
children: [
const Text("Diagnosis:" , style: TextStyle(fontSize: 30, height: 2, color: Colors.white)),
]),
Row(
children: [
const Text("Asthma, constipation" , style: TextStyle(fontSize: 30, height: 2, color: Colors.black)),
]),
Container(
margin: const EdgeInsets.fromLTRB(0, 25, 0, 0),
child: ElevatedButton.icon(
style: style,
icon: const Icon(Icons.edit),
label: const Text('Edit Health'),
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => const EditHealthApp()));
},
)
)]),
),
]));
}
}
At the moment, I have most fields hard coded. Although, in the home address field, i have tried to enter info.address. This obviously will not work, as I cannot initialise the userInfo object without being inside of an async function, but then I can't access the variables.

Related

:ui_dart_state.cc(209)] Unhandled Exception: NoSuchMethodError: The method '[]' was called on null. Receiver: null Tried calling: []("queryText")

hi everyone I have a flutter app and I want to integrate a chatbot with it I use dialog flow to create the bot and I writhe the code which is contain some commands for the screen and the messages but the code above are appearing to me + the response of the chatbot does not appear and I didn't know why , also I generate the json file and put it on the assets
this is my code
import 'package:bubble/bubble.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:dialogflow_flutter/dialogflowFlutter.dart';
import 'package:dialogflow_flutter/googleAuth.dart';
import 'package:dialogflow_flutter/language.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class chatBot extends StatefulWidget {
const chatBot({Key? key}) : super(key: key);
#override
_chatBotState createState() => _chatBotState();
}
class _chatBotState extends State<chatBot> {
final messageController = TextEditingController();
List<Map> messsages = [];
void response(query) async {
AuthGoogle authGoogle =
await AuthGoogle(fileJson: "Assets/images/service.json").build();
DialogFlow dialogflow =
DialogFlow(authGoogle: authGoogle, language: Language.english);
AIResponse aiResponse = await dialogflow.detectIntent(query);
setState(() {
messsages.insert(0, {
"data": 0,
"message": aiResponse.getListMessage()[0]["text"]["text"][0].toString()
});
});
print(aiResponse.getListMessage()[0]["text"]["text"][0].toString());
}
final messageInsert = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
"Chat bot",
),
),
body: Container(
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.only(top: 15, bottom: 10),
child: Text(
"Today, ${DateFormat("Hm").format(DateTime.now())}",
style: TextStyle(fontSize: 20),
),
),
Flexible(
child: ListView.builder(
reverse: true,
itemCount: messsages.length,
itemBuilder: (context, index) => chat(
messsages[index]["message"].toString(),
messsages[index]["data"]))),
SizedBox(
height: 20,
),
Divider(
height: 5.0,
color: Colors.greenAccent,
),
Container(
child: ListTile(
leading: IconButton(
icon: Icon(
Icons.camera_alt,
color: Colors.greenAccent,
size: 35,
),
onPressed: () {},
),
title: Container(
height: 35,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(15)),
color: Color.fromRGBO(220, 220, 220, 1),
),
padding: EdgeInsets.only(left: 15),
child: TextFormField(
controller: messageInsert,
decoration: InputDecoration(
hintText: "Enter a Message...",
hintStyle: TextStyle(color: Colors.black26),
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
),
style: TextStyle(fontSize: 16, color: Colors.black),
onChanged: (value) {},
),
),
trailing: IconButton(
icon: Icon(
Icons.send,
size: 30.0,
color: Colors.greenAccent,
),
onPressed: () {
if (messageInsert.text.isEmpty) {
print("empty message");
} else {
setState(() {
messsages.insert(
0, {"data": 1, "message": messageInsert.text});
});
response(messageInsert.text);
messageInsert.clear();
}
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
}),
),
),
SizedBox(
height: 15.0,
)
],
),
),
);
}
//for better one i have use the bubble package check out the pubspec.yaml
Widget chat(String message, int data) {
return Container(
padding: EdgeInsets.only(left: 20, right: 20),
child: Row(
mainAxisAlignment:
data == 1 ? MainAxisAlignment.end : MainAxisAlignment.start,
children: [
data == 0
? Container(
height: 60,
width: 60,
child: CircleAvatar(
backgroundImage: AssetImage("Assets/images/robot.jpg"),
),
)
: Container(),
Padding(
padding: EdgeInsets.all(10.0),
child: Bubble(
radius: Radius.circular(15.0),
color: data == 0
? Color.fromRGBO(23, 157, 139, 1)
: Colors.orangeAccent,
elevation: 0.0,
child: Padding(
padding: EdgeInsets.all(2.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
width: 10.0,
),
Flexible(
child: Container(
constraints: BoxConstraints(maxWidth: 200),
child: Text(
message,
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.bold),
),
))
],
),
)),
),
data == 1
? Container(
height: 60,
width: 60,
child: CircleAvatar(
backgroundImage: AssetImage("Assets/images/userphoto.jpeg"),
),
)
: Container(),
],
),
);
}
}
and this is the packages that I import on pubspec.yaml
dialogflow_flutter: ^0.0.3
bubble:
intl:
and this is the error appears to me
please help me

Flutter- click is responding to every item in listview.builder

I am trying to create a list of items in flutter with listView.builder, i am also using using elevatedButton in my itemBuilder.
i applied setState in button
i want to change value of single item only
but that is applying to every value in list
here is my code
import 'dart:developer';
import 'package:counter_button/counter_button.dart';
import 'package:flutter/material.dart';
import 'package:fooddeliveryapp/apis.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'models/restrauntmenu.dart';
class RestrauntPage extends StatefulWidget {
final String restrauntId;
final String restrauntName;
final String restrauntType;
final String restrauntApproxBill;
final String restrauntTagline;
const RestrauntPage(
{Key? key,
required this.restrauntId,
required this.restrauntType,
required this.restrauntApproxBill,
required this.restrauntTagline,
required this.restrauntName})
: super(key: key);
#override
State<RestrauntPage> createState() => _RestrauntPageState();
}
class _RestrauntPageState extends State<RestrauntPage> {
int _counterValue = 1;
bool itemAdded = false;
late Future<List<RestrauntMenu>> futureRestrauntMenu;
Future<List<RestrauntMenu>> fetchRestrauntMenu() async {
String restrauntId = widget.restrauntId;
final response = await http.get(Uri.parse(menuApi(restrauntId)));
if (response.statusCode == 200) {
final parsed = json.decode(response.body).cast<Map<String, dynamic>>();
return parsed
.map<RestrauntMenu>((json) => RestrauntMenu.fromMap(json))
.toList();
} else {
throw Exception('Failed to load album');
}
}
addToCartButton(
{required String? itemname,
required String? itemprice,
required int? itemCount,
required String? usermob,
required String? restrauntName}) {
return ElevatedButton(
clipBehavior: Clip.antiAliasWithSaveLayer,
style: ButtonStyle(
elevation: MaterialStateProperty.all(
6,
),
backgroundColor: MaterialStateProperty.all(Colors.white),
),
onPressed: () {
addToCart(
itemname: itemname,
itemprice: itemprice,
restrauntName: restrauntName,
usermob: usermob,
itemCount: itemCount);
},
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Text(
'ADD TO CART',
style: TextStyle(
color: Colors.green,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
);
}
counterButton() {
return Container(
decoration: const BoxDecoration(color: Colors.white),
child: CounterButton(
loading: false,
onChange: (int val) {
setState(() {
_counterValue = val;
});
},
count: _counterValue,
countColor: Colors.green,
buttonColor: Colors.black,
progressColor: Colors.black,
),
);
}
Future addToCart(
{required String? itemname,
required String? itemprice,
required int? itemCount,
required String? usermob,
required String? restrauntName}) async {
itemCount = _counterValue;
var url = addToCartApi(
itemname: itemname,
itemprice: itemprice,
itemCount: itemCount,
usermob: usermob,
restrauntName: restrauntName);
var response = await http.get(
Uri.parse(url),
);
if (response.statusCode == 200) {
setState(() {
itemAdded = true;
});
} else {
return false;
}
}
#override
void initState() {
futureRestrauntMenu = fetchRestrauntMenu();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
foregroundColor: Colors.black,
elevation: 0,
backgroundColor: Colors.white,
title: const Text('Restraunt Name'),
),
body: SingleChildScrollView(
child: SizedBox(
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
SizedBox(
width: MediaQuery.of(context).size.width * 0.03,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.restrauntName,
style: const TextStyle(
color: Colors.black,
fontSize: 24,
fontWeight: FontWeight.w900,
),
),
// const SizedBox(height: 4),
Text(
widget.restrauntType,
style: const TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.normal,
),
),
Text(
widget.restrauntTagline,
style: const TextStyle(
color: Colors.black87,
fontSize: 12,
fontWeight: FontWeight.normal,
),
),
const SizedBox(
height: 6,
),
Container(
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(10),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: RichText(
text: TextSpan(
children: [
const WidgetSpan(
child: Icon(
Icons.currency_rupee,
size: 16,
color: Color.fromARGB(255, 45, 174, 49),
),
),
TextSpan(
text: widget.restrauntApproxBill,
style: const TextStyle(
color: Colors.black,
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
),
],
),
const Spacer(),
Container(
decoration: BoxDecoration(
color: const Color.fromARGB(255, 49, 171, 53),
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: RichText(
text: const TextSpan(
children: [
TextSpan(
text: '3.6',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
WidgetSpan(
child: Icon(
Icons.star,
color: Colors.white,
size: 18,
),
),
],
),
),
),
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.03,
),
],
),
const SizedBox(
height: 12,
),
Expanded(
child: FutureBuilder<List<RestrauntMenu>>(
future: futureRestrauntMenu,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
return ExpansionTile(
initiallyExpanded: true,
childrenPadding: const EdgeInsets.all(8),
title: Text(
snapshot.data![index].catname!,
style: const TextStyle(
fontSize: 20, fontWeight: FontWeight.bold),
),
children: [
Row(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
snapshot.data![index].itemname!,
style: const TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 4,
),
Text(
snapshot.data![index].itemPrice!,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
),
),
const SizedBox(
height: 4,
),
Text(
snapshot.data![index].itemDescription!,
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.normal,
),
),
],
),
const Spacer(),
Stack(
alignment: Alignment.bottomCenter,
children: [
Padding(
padding:
const EdgeInsets.only(bottom: 16),
child: ClipRRect(
borderRadius:
BorderRadius.circular(10),
child: FittedBox(
child: Container(
height: MediaQuery.of(context)
.size
.height *
0.22,
width: MediaQuery.of(context)
.size
.width *
0.4,
decoration: BoxDecoration(
color: Colors.red,
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
'http://www.jfamoslogistics.com/images/${snapshot.data![index].itemimage!}',
),
),
),
),
),
),
),
Align(
alignment: Alignment.topRight,
child: itemAdded
? counterButton()
: addToCartButton(
itemprice: snapshot
.data![index].itemPrice,
itemname: snapshot
.data![index].itemname,
itemCount: _counterValue,
restrauntName:
widget.restrauntName,
usermob: '9354954343',
))
],
)
],
),
],
);
},
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return const Center(
child: CircularProgressIndicator(),
);
},
),
),
],
),
),
),
);
}
}
please check and help me
please let me know if i am missing something or making some mistake in code
i have tried google everywhere but nothing works
thanks in advance
As Giseppe Colucci described, you are using a single counter variable for a list . You can follow the simple approach of using list. On State
int _counterValue = 1; will be replaced with List<int> _counterValue = []
After getting data initialize the list with default value.
if (snapshot.hasData) {
_counterValue =List.generate(snapshot.data!.length, (index) => 1); // you might prefer default value as 0 instead of 1
As for the counter button method we need to update specific index, therefore we will pass index here
counterButton(int index) {
return Container(
decoration: const BoxDecoration(color: Colors.white),
child: CounterButton(
loading: false,
onChange: (int val) {
setState(() {
_counterValue[index] = val;
});
},
count: _counterValue[index],
Now whenever we use this counterButton method we need to pass index and here we get index from listview.
child: itemAdded
? counterButton(index)
: addToCartButton(
That is because your itemAdded bool is only one, for every item in the list, you should make a map, like this:
{'id':true}
where id is the restaurant menu item, and true is whenever the item is selected or not.
If this is too hard for you, just use a simple list.

flutter Problem same quantity show on products

when I am increasing my quantity of one product then all product's quantity is increasing, so how to solve it.
This is my product page:
import 'dart:convert';
import 'package:carousel_pro/carousel_pro.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hospital/Authentication/LoginLogoutScreenPage/login.dart';
import 'package:hospital/CartPage/Cart_Api/cart_api.dart';
import 'package:hospital/CartPage/pages/cartPage.dart';
import 'package:hospital/Drawer/dropdown_menu.dart';
import 'package:hospital/ProductDetailsPage/product_detailPage.dart';
import 'package:hospital/ProductDetailsPage/related_product_page.dart';
import 'package:hospital/SecondSection/Medicine/medicine_page.dart';
import 'package:hospital/constant.dart';
import 'package:hospital/customApiVariable.dart';
import 'package:http/http.dart' as http;
import 'package:line_icons/line_icons.dart';
import 'package:provider/provider.dart';
class DetailPage extends StatefulWidget {
final plistId;
const DetailPage({Key key, this.plistId}) : super(key: key);
#override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
final GlobalKey<FormState> _formKey = GlobalKey();
int quantity = 1;
var response;
var detailPageApi;
#override
void initState() {
super.initState();
fetchData(widget.plistId);
}
fetchData(var consultWithDoctor) async {
var api = Uri.parse(
'$ecommerceBaseUrl/productListApi.php?a2rTokenKey=$a2rTokenKey&plistId=${widget.plistId}');
response = await http.get(
api,
);
print("detailPageApi " + api.toString());
print("detailPageBody " + response.body);
detailPageApi = jsonDecode(response.body);
print("detailPagelist " + detailPageApi.toString());
setState(() {});
}
Future _submit() async {
var errorMessage = 'Authentication Failed';
if (successfully_add_cart_status.toString() == 'false') {
errorMessage = 'Please try again later';
print(errorMessage);
_showerrorDialog(errorMessage);
} else {
errorMessage = 'Product Succesfully Added to Cart';
print(errorMessage);
_showerrorDialog(errorMessage);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: kGreen,
title: Text(
"Details",
style: TextStyle(fontStyle: FontStyle.italic),
),
actions: [
IconButton(
icon: Icon(Icons.shopping_cart),
// onPressed: () => print("open cart"),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Cartpage()),
);
},
),
DropDownMenu(),
],
),
body: Container(
child: response != null
? ListView.builder(
itemCount: detailPageApi.length.clamp(0, 1),
scrollDirection: Axis.vertical,
physics: ScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, index) {
var details = detailPageApi[index];
if (details['num'] == 0) {
return Center(
child: CircularProgressIndicator(
backgroundColor: Colors.white,
),
);
}
return Column(
children: <Widget>[
Hero(
tag: "1",
child: SizedBox(
height: 300.0,
width: 300.0,
child: Carousel(
boxFit: BoxFit.cover,
autoplay: false,
animationCurve: Curves.fastOutSlowIn,
animationDuration: Duration(milliseconds: 800),
dotSize: 6.0,
dotIncreasedColor: Colors.black,
dotBgColor: Colors.transparent,
// dotPosition: DotPosition.topRight,
dotVerticalPadding: 10.0,
showIndicator: true,
indicatorBgPadding: 7.0,
images: [
NetworkImage(details['pImgImg']),
],
),
),
),
SizedBox(
height: 50,
),
Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Name :",
style: TextStyle(
fontSize: 18,
height: 1.5,
fontWeight: FontWeight.w500),
),
SizedBox(
width: 20,
),
Flexible(
child: Text(
// widget.details,
details['productName'],
style: TextStyle(
fontSize: 17,
height: 1.5,
fontWeight: FontWeight.w500),
),
),
],
),
),
SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Details :",
style: TextStyle(
fontSize: 18,
height: 1.5,
fontWeight: FontWeight.w500),
),
SizedBox(
width: 20,
),
Flexible(
child: Text(
// widget.details,
details['productDescription'],
style: TextStyle(
fontSize: 17,
height: 1.5,
fontWeight: FontWeight.w500),
),
),
],
),
),
SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: Row(
children: <Widget>[
Text(
"Price :",
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.w500),
),
SizedBox(
width: 20,
),
Row(
children: <Widget>[
Text(
// "Rs " + widget.pPromotionPrice,
"Rs 55.0",
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.w500),
),
SizedBox(
width: 20,
),
Text(
// "Rs " + widget.pPrice,
"Rs 100",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
// color: warning,
decoration: TextDecoration.lineThrough),
)
],
)
],
),
),
SizedBox(
height: 25,
),
Padding(
padding: const EdgeInsets.only(right: 20, left: 20),
child: Row(
children: <Widget>[
Text(
"Qty :",
style: TextStyle(
fontSize: 17, fontWeight: FontWeight.w500),
),
SizedBox(
width: 20,
),
Row(
children: <Widget>[
InkWell(
onTap: () {
if (quantity > 1) {
setState(() {
quantity = --quantity;
});
}
// minus here
},
child: Container(
width: 25,
height: 25,
decoration: BoxDecoration(
// border: Border.all(color: primary),
shape: BoxShape.circle),
child: Icon(
LineIcons.minus,
size: 15,
),
),
),
SizedBox(
width: 15,
),
Text(
quantity.toString(),
style: TextStyle(fontSize: 16),
),
SizedBox(
width: 15,
),
InkWell(
onTap: () {
setState(() {
quantity = ++quantity;
});
// minus here
},
child: Container(
width: 25,
height: 25,
decoration: BoxDecoration(
// border: Border.all(color: primary),
shape: BoxShape.circle),
child: Icon(
LineIcons.plus,
size: 15,
),
),
),
],
)
],
),
),
SizedBox(
height: 50,
),
InkWell(
onTap: () async {
if (var_uid.toString() != null.toString()) {
_submit();
var qty = quantity.toString();
var plistId = widget.plistId;
print('pplistid' + plistId);
var uid = var_uid.toString();
var sid = var_sid.toString();
print('uuid' + uid);
print('ssid' + sid);
var response =
await add_to_cart_fn(qty, plistId, uid, sid);
print("rsp: " + response['msg']);
} else {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => LoginPage()));
}
},
// },
child: Padding(
padding: EdgeInsets.only(left: 20, right: 20),
child: Container(
height: 45,
width: double.infinity,
decoration: BoxDecoration(
color: kGreen,
borderRadius: BorderRadius.circular(30)),
child: Center(
child: Text(
"ADD TO CART",
style: TextStyle(
color: kWhite,
fontSize: 20,
),
),
),
),
),
),
SizedBox(height: 20.0),
RelatedProductPage(plistId: widget.plistId)
],
);
})
: Center(
child: CircularProgressIndicator(
backgroundColor: Colors.white,
),
),
),
);
}
void _showerrorDialog(String message) {
Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
backgroundColor: Colors.grey[350],
textColor: Colors.black,
fontSize: 16.0);
}
}
You are using the same quantity variable against each item. Changing the value on one of those will cause all items to update. What you need to do is to keep a Map of quantity selected against product id. That way whenever you increase or decrease the quantity, you update the quantity against that specific product id and the rest will remain unchanged.
EDIT: Here is how this will work
//Create a new map to save the product id and product selected quantity
var productQuantity = new Map<int, int>()
//When setting the values of the product, set the quantity from the map
Padding(
padding: const EdgeInsets.only(right: 20, left: 20),
child: Row(
children: <Widget>[
Text(
"Qty :",
style: TextStyle(
fontSize: 17, fontWeight: FontWeight.w500),
),
SizedBox(width: 20,),
Row(
children: <Widget>[
InkWell(
onTap: () {
if (quantity > 1) {
setState(() {
//Changed here
productQuantity['$productId'] -= 1;
});
}
},
child: Container(
width: 25,
height: 25,
decoration: BoxDecoration(shape: BoxShape.circle),
child: Icon(
LineIcons.minus,
size: 15,
),
),
),
SizedBox(width: 15,),
Text(
//Changed here
productQuantity['$productId'].toString(),
style: TextStyle(fontSize: 16),
),
SizedBox(width: 15,),
InkWell(
onTap: () {
setState(() {
//Changed here
productQuantity['$productId'] += 1;
});
},
child: Container(
width: 25,
height: 25,
decoration: BoxDecoration(
shape: BoxShape.circle),
),
child: Icon(
LineIcons.plus,
size: 15,
),
),
),
],
)
],
),
)
you set the common quantity in all products so change it and set it inside the class.
Please Check the example
import 'package:flutter/material.dart';
class QuantityUpdatePage extends StatefulWidget {
#override
_QuantityUpdatePageState createState() => _QuantityUpdatePageState();
}
class _QuantityUpdatePageState extends State<QuantityUpdatePage> {
List<Product> productArray = [];
#override
void initState() {
super.initState();
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
productArray.clear();
productArray.add(Product(1, "Product 1", 1));
productArray.add(Product(2, "Product 2", 1));
productArray.add(Product(3, "Product 3", 1));
productArray.add(Product(4, "Product 4", 1));
productArray.add(Product(5, "Product 5", 1));
setState(() {});
});
}
#override
void dispose() {
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("QUANTITY UPDATE")),
body: ListView.builder(
shrinkWrap: true,
itemCount: productArray.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.only(right: 20, left: 20),
child: ListView(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
children: [
SizedBox(
height: 20,
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(productArray[index].productName),
SizedBox(
width: 40,
),
Row(
children: <Widget>[
Text(
"Qty :",
style: TextStyle(fontSize: 17, fontWeight: FontWeight.w500),
),
SizedBox(
width: 20,
),
Row(
children: <Widget>[
InkWell(
onTap: () {
if (productArray[index].quantity > 1) {
setState(() {
productArray[index].quantity = --productArray[index].quantity;
});
}
// minus here
},
child: Container(
width: 25,
height: 25,
decoration: BoxDecoration(
// border: Border.all(color: primary),
shape: BoxShape.circle),
child: Icon(
Icons.minimize,
size: 15,
),
),
),
SizedBox(
width: 15,
),
Text(
productArray[index].quantity.toString(),
style: TextStyle(fontSize: 16),
),
SizedBox(
width: 15,
),
InkWell(
onTap: () {
setState(() {
productArray[index].quantity = ++productArray[index].quantity;
});
// minus here
},
child: Container(
width: 25,
height: 25,
decoration: BoxDecoration(
// border: Border.all(color: primary),
shape: BoxShape.circle),
child: Icon(
Icons.add,
size: 15,
),
),
),
],
)
],
),
],
),
SizedBox(
height: 20,
),
],
),
);
}));
}
}
class Product {
String productName;
int quantity;
int id;
Product(this.id, this.productName, this.quantity);
}
#Deepak if you don't understand Maps use list instead, with a value being updated for each index. Initialize a list of int types with some large values like 1000000, and update the value for each index. use ListView builder to fetch the data from the API for each index.
List<int> quantity = List.empty(growable: true);
OR
List<int> quantity = List.filled(10000, []);
For updating quantity:-
quantity[index] += 1;
For Grid view thing, refer this example from CodeGrepper:-
GridView.count(
// Create a grid with 2 columns. If you change the scrollDirection to
// horizontal, this produces 2 rows.
crossAxisCount: 2,
// Generate 100 widgets that display their index in the List.
children: List.generate(100, (index) {
return Center(
child: Text(
'Item $index',
style: Theme.of(context).textTheme.headline5,
),
);
}),
);

how to reduce the gap between this widgets? I tried tweaking padding values but no luck so far. Please take a look

This is the code
I tweaked the paading but no luck. I am new to flutter manage to build this but stuck, any suggestions/help is much appreciated!
import 'package:bmi_app_one/utils/TextStyle_Decorations.dart';
import 'package:bmi_app_one/utils/hexcolor.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_icons/flutter_icons.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class home_screen extends StatefulWidget {
#override
_home_screenState createState() => _home_screenState();
}
class _home_screenState extends State<home_screen> {
Color _appBar_bg_color = HexColor('#1C1C1E');
Color _app_bg_color = HexColor('#2c2c2e');
bool changeButtonColorMale = false;
bool changeButtonColorFemale = false;
int age = 20;
int weight = 30;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: homeScreenAppBarText,
backgroundColor: _appBar_bg_color,
centerTitle: true,
),
backgroundColor: _app_bg_color,
body: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
width: ScreenUtil().screenWidth,
height: 0.6.sh,
child: Row(
/* Entry Point of 1st set */
children: [
/* This contains both Male and female gender button */
Column(
children: [
Row(
children: [
/* Male Button */
Padding(
padding: const EdgeInsets.fromLTRB(8, 8, 4, 8),
child: InkWell(
onTap: (){
debugPrint("Gender: Male pressed");
setState(() {
if(changeButtonColorMale == false){
changeButtonColorMale = true;
changeButtonColorFemale = false;
}
else{
changeButtonColorMale = false;
}
});
},
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
child: Container(
width: 0.4.sw,
height: 0.2.sh,
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
borderRadius: BorderRadius.circular(8.0)
),
margin: EdgeInsets.all(10),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(12.0),
child: Icon(Ionicons.ios_male,size: 88.ssp,
color: changeButtonColorMale ? Colors.yellow.withOpacity(0.7) : Colors.white),
),
Text(
"Male", style: TextStyle(
fontSize: 24.ssp,
fontFamily: 'San francisco',
color: changeButtonColorMale ? Colors.yellow.withOpacity(0.7) : Colors.white
),
),
],
),
),
),
),
/* Age */
Padding(
padding: const EdgeInsets.fromLTRB(0, 8, 8, 8),
child: Container(
width: 0.43.sw,
height: 0.2.sh,
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
borderRadius: BorderRadius.circular(8.0)
),
child: Column(
children: [
/* Age Text */
Padding(
padding: const EdgeInsets.fromLTRB(8, 36, 8, 8),
child: Text("AGE",
style: TextStyle(
fontSize: 24.ssp,
fontFamily: 'San francisco',
color: Colors.white
),
),
),
Row(
children: [
/* Age decrease icon */
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
child: IconButton(
icon: new Icon(
MaterialCommunityIcons.minus_circle_outline,
size: 42.ssp,
color: Colors.white,),
onPressed: (){
debugPrint("Age decreased by 1");
setState(() {
if(age <= 5){
}
else{
age --;
}
});
},
splashRadius: 0.1,
),
),
/* Display Age in numbers */
Padding(
padding: const EdgeInsets.fromLTRB(15, 8 , 0, 0),
child: Text(age.toString(),
style: TextStyle(
color: Colors.white,
fontSize: 26.ssp,
fontFamily: 'San francisco',
),
),
),
/* Age increase icon */
Padding(
padding: const EdgeInsets.fromLTRB(3, 0, 0, 0),
child: IconButton(
icon: new Icon(
MaterialCommunityIcons.plus_circle_outline,
size: 42.ssp,
color: Colors.white,),
onPressed: (){
debugPrint("Age increased by 1");
setState(() {
if(age >= 90){
}
else{
age ++;
}
});
},
splashRadius: 0.1,
),
)
],
)
],
),
),
)
],
),
Row(
children: [
/* Female Button */
Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 4, 0),
child: new InkWell(
onTap: (){
debugPrint("Gender: Female pressed");
setState(() {
if(changeButtonColorFemale == false){
changeButtonColorFemale = true;
changeButtonColorMale = false;
}
else{
changeButtonColorFemale = false;
}
});
},
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
child: Container(
width: 0.4.sw,
height: 0.2.sh,
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
borderRadius: BorderRadius.circular(8.0)
),
margin: EdgeInsets.all(10.0),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(12.0),
child: Icon(Ionicons.ios_female,size: 88.ssp,
color: changeButtonColorFemale ? Colors.yellow.withOpacity(0.7) : Colors.white),
),
Text(
"Female", style: TextStyle(
fontSize: 24.ssp,
fontFamily: 'San francisco',
color: changeButtonColorFemale ? Colors.yellow.withOpacity(0.7) : Colors.white
),
),
],
),
),
),
),
/* Weight */
Padding(
padding: const EdgeInsets.fromLTRB(0, 8, 8, 8),
child: Container(
width: 0.43.sw,
height: 0.2.sh,
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
borderRadius: BorderRadius.circular(8.0)
),
child: Column(
children: [
/* Weight Text */
Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(24, 36, 3, 8),
child: Text("WEIGHT",
style: TextStyle(
fontSize: 24.ssp,
fontFamily: 'San francisco',
color: Colors.white
),
),
),
Text("(Kg)",
style: TextStyle(
color: Colors.white.withOpacity(0.7),
fontSize: 11.ssp,
fontFamily: 'San francisco',
),
),
],
),
Row(
children: [
/* Weight decrease icon */
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
child: IconButton(
icon: new Icon(
MaterialCommunityIcons.minus_circle_outline,
size: 42.ssp,
color: Colors.white,),
onPressed: (){
debugPrint("Weight decreased by 1");
setState(() {
if(weight <= 5){
}
else{
weight --;
}
});
},
splashRadius: 0.1,
),
),
/* Display Weight in numbers */
Padding(
padding: const EdgeInsets.fromLTRB(15, 8 , 0, 0),
child: Text(weight.toString(),
style: TextStyle(
color: Colors.white,
fontSize: 26.ssp,
fontFamily: 'San francisco',
),
),
),
/* Weight increase icon */
Padding(
padding: const EdgeInsets.fromLTRB(3, 0, 0, 0),
child: IconButton(
icon: new Icon(
MaterialCommunityIcons.plus_circle_outline,
size: 42.ssp,
color: Colors.white,),
onPressed: (){
debugPrint("Weight increased by 1");
setState(() {
if(weight >= 625){
}
else{
weight ++;
}
});
},
splashRadius: 0.1,
),
)
],
)
],
),
),
),
],
)
],
),
],
),
),
/* Height Slider 2nd set */
Container(
width: ScreenUtil().screenWidth,
height: 0.15.sh,
decoration: BoxDecoration(
color: Colors.white
),
child: Column(
children: [],
),
)
],
),
)
);
}
}
This is the screenshot at present
tweaked the paading but no luck. I am new to flutter manage to build this but stuck, any suggestions/help is much appreciated!
You're creating that extra space with how you're setting the height of the 2nd Container at the top of your build method. I assume that the sh in height: 0.6.sh, is ScreenHeight * 0.6?
It doesn't appear that either of those first 2 Container's are adding anything of value. You can just remove them both and your white Container at the bottom should jump up closer to everything else.

trying to add to bag and to update prices and cups

I am trying to do this test TODOs: but i have been have issuses pls help: i am trying to Uncomment the _confirmOrderModalBottomSheet() method to show summary of order, Uncomment the setState() function to clear the price and cups, and Change the 'price' to 0 when this button is clicked Increment the _cupsCounter when 'Add to Bag' button is clicked, and to Call setState((){}) method to update both price and cups counter when 'Add to Bag' button is clicked
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Coffee Test',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.white,
),
home: MyHomePage(title: 'Coffee Test'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _selectedPosition = -1;
String _coffeePrice ="0";
int _cupsCounter =0;
int price = 0;
String _currency ="₦";
static const String coffeeCup ="images/coffee_cup_size.png";
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
title: FlatButton(
onPressed: (){
//TODO: Uncomment the _confirmOrderModalBottomSheet() method to show summary of order
//_confirmOrderModalBottomSheet(totalPrice: "$_currency$price", numOfCups: "x $_cupsCounter");
},
child: Text("Buy Now",style: TextStyle(color: Colors.black87),),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(18.0), side: BorderSide(color: Colors.blue))
),
actions: [
InkWell(
onTap: () {
//TODO: Uncomment the setState() function to clear the price and cups
//TODO: Change the 'price' to 0 when this button is clicked
setState(() {
this.price = -1;
this._cupsCounter = 0;
});
Icon(Icons.clear);
}),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Container(
height: double.maxFinite,
alignment: Alignment.center,
child: Text("$_cupsCounter Cups = $_currency$price.00", style: TextStyle(fontSize: 18),),
),
)
],
),
body: Padding(padding: EdgeInsets.all(20), child: _mainBody(),) // This trailing comma makes auto-formatting nicer for build methods.
);
}
Widget _mainBody(){
return SingleChildScrollView(
child: Container(
height: double.maxFinite,
width: double.maxFinite,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 0,
child: Stack(
children: [
Container(
width: double.maxFinite,
height: 250,
margin: EdgeInsets.only(left: 50, right: 50, bottom: 50, top: 60),
decoration: BoxDecoration(borderRadius:
BorderRadius.all(Radius.circular(180)),
color: Color.fromRGBO(239, 235, 233, 100)),
),
Container(
alignment: Alignment.center,
width: double.maxFinite,
height: 350,
child: Image.asset("images/cup_of_coffee.png", height: 300,),
)
],
)),
Padding(padding: EdgeInsets.all(10),),
Expanded(flex: 0,child: Text("Caffè Americano",
style: TextStyle(fontWeight: FontWeight.bold,
fontSize: 30),)),
Padding(padding: EdgeInsets.all(6),),
Expanded(flex: 0, child: Text("Select the cup size you want and we will deliver it to you in less than 48hours",
style: TextStyle(fontWeight: FontWeight.bold,
fontSize: 14, color: Colors.black45,),
textAlign: TextAlign.start,),
),
Container(
margin: EdgeInsets.only(top: 30, left: 20),
height: 55,
width: double.maxFinite,
alignment: Alignment.center,
child:Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
RichText(text: TextSpan(
text: _currency,
style: TextStyle(fontWeight: FontWeight.bold,
fontSize: 25, color: Colors.black87),
children: [
TextSpan(text: _coffeePrice, style: TextStyle(fontSize: 50, fontWeight: FontWeight.bold))
]
),),
Padding(
padding: EdgeInsets.only(right: 15),
),
ListView.builder(itemBuilder: (context, index){
return InkWell(
child: _coffeeSizeButton(_selectedPosition == index,
index ==0? "S" : index ==1? "M": "L"),
onTap: (){
setState(() {
this._coffeePrice= index ==0? "300" : index ==1? "600": "900";
_selectedPosition = index;
});
},
);
}, scrollDirection: Axis.horizontal,
itemCount: 3, shrinkWrap: true,),
],),
),
Container(
margin: EdgeInsets.only(top: 30),
padding: EdgeInsets.all(10),
width: double.maxFinite,
height: 70,
child: FlatButton(onPressed: (){
//TODO: Currently _cupsCounter only show 1 when this button is clicked.
// TODO: Increment the _cupsCounter when 'Add to Bag' button is clicked'
//TODO: Call setState((){}) method to update both price and cups counter when 'Add to Bag' button is clicked
this._cupsCounter = 1;
this.price += int.parse(_coffeePrice);
}, child: Center(child: Text("Add to Bag",
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white),)
,),
color: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50)
),
),
)
],
),
),
);
}
Widget _coffeeSizeButton(bool isSelected, String coffeeSize){
return Stack(
children: [
Container(alignment: Alignment.center, width: 55,
child: Text(coffeeSize, style: TextStyle(fontSize: 10, fontWeight: FontWeight.bold,
color: isSelected? Colors.blue: Colors.black45),),),
new Container(
margin: EdgeInsets.only(right: 10),
child: Image.asset(coffeeCup, width:50, color: isSelected ? Colors.blue: Colors.black45,),
decoration: BoxDecoration(border: Border(top: BorderSide(color: isSelected? Colors.blue: Colors.black45,
width: isSelected? 2: 1), left: BorderSide(color: isSelected? Colors.blue: Colors.black45,
width: isSelected? 2: 1), bottom: BorderSide(color: isSelected? Colors.blue: Colors.black45,
width: isSelected? 2: 1), right: BorderSide(color: isSelected ?Colors.blue: Colors.black45 ,
width: isSelected? 2: 1)), borderRadius: BorderRadius.all(Radius.circular(5))),
)
],
);
}
void _confirmOrderModalBottomSheet({String totalPrice, String numOfCups}){
showModalBottomSheet(
context: context,
builder: (builder){
return new Container(
height: 150.0,
color: Colors.transparent, //could change this to Color(0xFF737373),
//so you don't have to change MaterialApp canvasColor
child: new Container(
padding: EdgeInsets.all(10),
decoration: new BoxDecoration(
color: Colors.white,
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(10.0),
topRight: const Radius.circular(10.0))),
child: Column(
children: [
Container(
child: Text("Confirm Order",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),),
alignment: Alignment.center, height: 30, decoration: BoxDecoration(
), ),
_getEstimate(totalPrice, numOfCups)
],
)),
);
}
);
}
Widget _getEstimate(String totalPrice, String numOfCups){
return Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Image.asset("images/cup_of_coffee.png", height: 70, width: 50,),
Padding(padding: EdgeInsets.all(10)),
Text(numOfCups, style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),),
Padding(padding: EdgeInsets.all(10)),
Text(totalPrice, style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),)
],
);
}
}
You're setting 1 to your _cupsCounter instead of adding one to it.
When updating your values, putting the operation i.e _cupsCounter += 1; in setState will update the state of your widget which makes values change in your widgets.
setState((){
_cupsCounter += 1; // make it +=1 instead of =1.
price += int.parse(_coffeePrice);
});
Also you can use setState by putting it after your operation which will update the state of your widget after the operation is done.
_cupsCounter += 1; // make it +=1 instead of =1.
price += int.parse(_coffeePrice);
setState((){});
Full code should look like this.
Container(
margin: EdgeInsets.only(top: 30),
padding: EdgeInsets.all(10),
width: double.maxFinite,
height: 70,
child: FlatButton(onPressed: (){
// Currently _cupsCounter only show 1 when this button is clicked.
// Increment the _cupsCounter when 'Add to Bag' button is clicked'
// Call setState((){}) method to update both price and cups counter when 'Add to Bag' button is clicked
setState((){
_cupsCounter += 1; // make it +=1 instead of =1.
price += int.parse(_coffeePrice);
}); // call setState like this
}, child: Center(child: Text("Add to Bag",
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white),)
,),
color: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50)
),
),
)