Flutter concatenate bool variable with loop index - android

I have data in getData() from API and there is a list of data shown in UI and every item in the list is clickable. so want to add a bool type variable in for loop with the value i but I don't know how to concatenate the variable name with i. and the working of this bool variable in _navigateSlide(BuildContext context) widget. so when i add a bool variable in for loop with index i in getData() like
for (int i = 0; i < value.length; i++) { bool check[i] = false; }
it shows me an error of
Illegal assignment to non-assignable expression. Missing selector such as '.identifier' or '[0]'. on code check[i]
Here is my code:-
class ExploreAds extends StatefulWidget {
ExploreAds({Key? key}) : super(key: key);
#override
_ExploreAds createState() => _ExploreAds();
}
class _ExploreAds extends State<ExploreAds> {
bool show = false;
bool checkother = false;
final List<String> data = <String>[];
void addValue(txt) {
setState(() {
data.add('${txt}');
});
print(data);
}
void removeValue(rmtxt) {
setState(() {
data.remove('${rmtxt}');
});
print(data);
}
var catdata;
#override
void initState() {
super.initState();
getData();
}
getData() async{
await BuySellCatsController().buysellCatAPI().then((value) {
for (int i = 0; i < value.length; i++) {
bool check[i] = false;
}
}
);
}
#override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
final ThemeData themeData = Theme.of(context);
const double padding = 25;
const sidePadding = EdgeInsets.symmetric(horizontal: padding);
return Scaffold(
body: Container(
height: 550,
child: catdata != null?
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
addVerticalSpace(10),
Expanded(
child : Container(
child: GridView(
padding: EdgeInsets.only(right:8,),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 20,
mainAxisSpacing: 20,
childAspectRatio: 0.70,
),
children: List.generate(catdata.length + 1,
(index) => index == catdata.length ?
Stack(
children: [
Container(
padding: EdgeInsets.only(right:5, left:5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Color(0xffacacac)),
),
child: InkWell(
onTap: () => setState(
() {
checkother = !checkother ;
checkother ? addValue('Others') : removeValue('Others');
},
),
child: Column(
children: [
Image.asset('assets/icons/pngwing49.png', width: 115, height: 115),
Text('Others')
],
)
),
),
Visibility(
visible: check6 ? true : false,
child: Positioned(
top: 5,
right: 5,
child: Image.asset('assets/icons/tick.png', width: 15,),
)
)
],
):
Stack(
children: [
Container(
padding: EdgeInsets.only(right:5, left:5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Color(0xffacacac)),
),
child: InkWell(
onTap: () => setState(
() {
check[index] = !check[index];
check[index]? addValue('${catdata[index]['name']}') : removeValue('${catdata[index]['name']}');
},
),
child: Column(
children: [
Image.network('${catdata[index]['image']}', width: 115, height: 115,),
Text('${catdata[index]['name']}')
],
)
),
),
Visibility(
visible: check[index] ? true : false,
child: Positioned(
top: 5,
right: 5,
child: Image.asset('assets/icons/tick.png', width: 15,),
)
)
],
)
),
),
),
),
addVerticalSpace(10),
Padding(
padding: EdgeInsets.fromLTRB(20, 0, 20, 0),
child: ElevatedButton(
onPressed: () => Navigator.pop(context, 'Cancel'),
style: ElevatedButton.styleFrom(
elevation: 6,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(80.0)),
padding: const EdgeInsets.all(0.0),
),
child: Ink(
decoration: const BoxDecoration(
gradient: LinearGradient(colors: [Color(0xfff9568f), Color(0xfffabaae)],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
child: Container(
constraints: const BoxConstraints(minWidth: 88.0, minHeight: 50.0), // min sizes for Material buttons
alignment: Alignment.center,
child: const Text(
'Apply',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
),
),
),
)
],
):
const Center(
child: CircularProgressIndicator(
backgroundColor: Colors.white,
strokeWidth: 2,
color: Color(0xffe93332),
)
),
)
);
}
}
please help how can I do this? if anyone knows please help me.

You are declaring and assigning a variable inside the loop.
From your code, I'm assuming you want to get a list of bool values, that should have the length equal to value.length - all set to fale.
Note - no need to use .then when you are already using await.
You shoud have something like this:
Future<List<bool>> getData() async{
var value = await BuySellCatsController().buysellCatAPI();
return List.filled(value.length, false);
}
If you really wanted to use .then and for loop, here's how it would work
Future<List<bool>> getData() async{
return await BuySellCatsController().buysellCatAPI().then((value) {
var check=<bool>[];
for (int i = 0; i < value.length; i++) {
check.add(false);
}
}
);
}

Related

Updating text value with new discount amount in flutter

I'm making a food ordering app in which I want to provide a discount feature. I've implemented most of the part but I'm getting stuck at a point where I basically want to update the totalAmount with the discountRate.
class CartScreen extends StatefulWidget
{
final String? sellerUID;
const CartScreen({super.key, this.sellerUID});
#override
_CartScreenState createState() => _CartScreenState();
}
class _CartScreenState extends State<CartScreen>
{
List<int>? separateItemQuantityList;
num totalAmount = 0;
final _couponText = TextEditingController();
#override
void initState() {
super.initState();
totalAmount = 0;
Provider.of<TotalAmount>(context, listen: false).displayTotalAmount(0);
separateItemQuantityList = separateItemQuantities();
}
#override
Widget build(BuildContext context) {
var _coupon = Provider.of<CouponProvider>(context);
double discountRate = _coupon.discount/100;
return Scaffold(
appBar: AppBar(
title: const Text("Cart"),
flexibleSpace: Container(decoration: BoxDecoration(color: myColor),),
automaticallyImplyLeading: true,
),
body: CustomScrollView(
slivers: [
//display cart items with quantity number
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection("items")
.where("itemID", whereIn: separateItemIDs())
.orderBy("publishedDate", descending: true)
.snapshots(),
builder: (context, snapshot)
{
return !snapshot.hasData
? SliverToBoxAdapter(child: Center(child: circularProgress(),),)
: snapshot.data!.docs.isEmpty
? const SliverToBoxAdapter(child: Center(child: Padding(
padding: EdgeInsets.only(top: 300),
child: Text("The cart is empty",style: TextStyle(
fontSize: 24, fontWeight: FontWeight.bold),),
)))
: SliverList(
delegate: SliverChildBuilderDelegate((context, index)
{
Items model = Items.fromJson(
snapshot.data!.docs[index].data()! as Map<String, dynamic>,
);
if(index == 0)
{
totalAmount = 0;
totalAmount = totalAmount + (model.price! * separateItemQuantityList![index]);
}
else
{
totalAmount = totalAmount + (model.price! * separateItemQuantityList![index]);
}
if(snapshot.data!.docs.length - 1 == index)
{
WidgetsBinding.instance.addPostFrameCallback((timeStamp)
{
Provider.of<TotalAmount>(context, listen: false).displayTotalAmount(totalAmount.toDouble());
});
}
return CartItemDesign(
model: model,
context: context,
quanNumber: separateItemQuantityList![index],
);
},
childCount: snapshot.hasData ? snapshot.data!.docs.length : 0,
),
);
},
),
SliverFillRemaining(
hasScrollBody: false,
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
decoration: BoxDecoration(
color: const Color(0xfffb9e5a).withOpacity(0.6),
borderRadius: const BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20)),
),
width: double.infinity,
height: 160,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 12, 8, 6),
child: Column(
children: [
Consumer2<TotalAmount, CartItemCounter>(builder: (context, amountProvider, cartProvider, c){
return Center(
child: cartProvider.count == 0
? const Text("Please add something in the cart", style: TextStyle(fontSize: 18),)
: Column(
children: [
Text("The total amount is ₹${amountProvider.tAmount.toString()}", style: const TextStyle(fontSize: 18)),
const SizedBox(height: 10,),
Container(
height: 50,
width: MediaQuery.of(context).size.width * 8,
decoration: BoxDecoration(
border: Border.all(color: myColor, width: 1,),
borderRadius: const BorderRadius.all(Radius.circular(20)),
color: Colors.white54
//color: Colors.white54
),
child: Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.only(left: 10, right: 15),
child: TextField(
controller: _couponText,
maxLines: 1,
decoration: const InputDecoration.collapsed(
hintText: 'Apply coupon here ...'
),
),
),
),
Padding(
padding: const EdgeInsets.only(right: 10),
child: ElevatedButton(
onPressed: (){
_coupon.getcouponDetails(_couponText.text).then((value) {
if(value.data() == null){
setState(() {
_coupon.discount = 0;
});
showCodeDialog(_couponText.text, 'not valid');
return;
}
if(_coupon.expired==false){
// Code to be done here.
Fluttertoast.showToast(msg: 'Coupon is valid');
// I want to update the totalAmount value with the discountRate here...
}
if(_coupon.expired==true){
setState(() {
_coupon.discount = 0;
});
showCodeDialog(_couponText.text, 'expired');
return;
}
});
},
style: ElevatedButton.styleFrom(
textStyle: const TextStyle(
fontSize: 15,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
)
),
child: const Text('Apply'),
),
),
],
),
),
const SizedBox(height: 10,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton.icon(
onPressed: (){
clearCartNow(context);
Navigator.pop(context);
Navigator.push(context, MaterialPageRoute(builder: (c) => const HomeScreen()));
Fluttertoast.showToast(msg: "Cart cleared");
},
style: ElevatedButton.styleFrom(
foregroundColor: Colors.black, backgroundColor: myColor
),
icon: const Icon(Icons.clear_all),
label: const Text("Clear")),
ElevatedButton.icon(
onPressed: (){
Navigator.pop(context);
Navigator.push(context, MaterialPageRoute(builder: (c)=> AddressScreen(
totalAmount: totalAmount.toDouble(),
sellerUID: widget.sellerUID,
),
),
);
},
style: ElevatedButton.styleFrom(
foregroundColor: Colors.black,
backgroundColor: myColor,
),
icon: const Icon(Icons.navigate_next),
label: const Text("Proceed")),
],
)
],
),
);
}),
],
),
)
),
),
)
],
),
);
}
showCodeDialog(code, validity){
showCupertinoDialog(
context: context,
builder: (BuildContext context){
return CupertinoAlertDialog(
title: const Text('Apply Coupon'),
content: Text('This discount coupon $code you have entered is $validity'),
actions: [
Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: (){Navigator.pop(context);},
child: Text('Ok', style: TextStyle(color: Colors.white),),
),
)
],
);
});
}
}
I tried changing the totalAmount, amountProvider.tAmount and their types, but nothing is working for me.
In this image, the total amount is without discount. If I apply a coupon of 10%, the total amount should be subtracted by 10%.
I can add more information if required.

Flutter- Can border radius be given to Expansion Panel list? If yes, what are the properties that should be used

I have this code for expansion panel list which is working fine but I am not able to extend the size of the expansion panel. Also, I want the expansion panel to have a border radius but I am not sure if border radius can be given
return Column(children: [
Stack(
clipBehavior: Clip.none,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 50),
child: ExpansionPanelList(
animationDuration: Duration(milliseconds: 1000),
children: [
ExpansionPanel(
headerBuilder: (context, isExpanded) {
return Column(
children: [
Text("Salmon Poké"),
Text("Rs. 2000"),
],
);
},
body: Text(
'This salmon sashimi is a delicious light appetizer served with fresh wasabi, ginger, soy sauce or a delicious side of soy yuzo citrus ponzu.',
style: TextStyle(
fontSize: 18,
color: Colors.black,
),
),
isExpanded: _expanded,
canTapOnHeader: true,
backgroundColor: Colors.white),
],
dividerColor: Colors.grey,
expansionCallback: (panelIndex, isExpanded) {
_expanded = !_expanded;
setState(() {});
},
),
),
Positioned(
top: -55,
right: 240,
child: CircleAvatar(
radius: 105,
child: ClipOval(
child: Image(
image: AssetImage('assets/images/salmon.png'),
),
),
backgroundColor: Colors.transparent,
),
),
],
),
]);
}
}
**Here is the UI for the given code **
This is the output I have.
Here is the output which I want. (This UI is made using container widgets but I want this layout using expansion panel list)
This is the output that I want
I really appreciate your help.
For border radius we need to make custom expansion list
import 'package:flutter/material.dart';
const double _kPanelHeaderCollapsedHeight = 48.0;
const double _kPanelHeaderExpandedHeight = 64.0;
class CustomExpansionPanelList extends StatelessWidget {
const CustomExpansionPanelList(
{Key key,
this.children: const <ExpansionPanel>[],
this.expansionCallback,
this.animationDuration: kThemeAnimationDuration})
: assert(children != null),
assert(animationDuration != null),
super(key: key);
final List<ExpansionPanel> children;
final ExpansionPanelCallback expansionCallback;
final Duration animationDuration;
bool _isChildExpanded(int index) {
return children[index].isExpanded;
}
#override
Widget build(BuildContext context) {
final List<Widget> items = <Widget>[];
const EdgeInsets kExpandedEdgeInsets = const EdgeInsets.symmetric(
vertical: _kPanelHeaderExpandedHeight - _kPanelHeaderCollapsedHeight);
for (int index = 0; index < children.length; index += 1) {
if (_isChildExpanded(index) && index != 0 && !_isChildExpanded(index - 1))
items.add(new Divider(
key: new _SaltedKey<BuildContext, int>(context, index * 2 - 1),
height: 15.0,
color: Colors.transparent,
));
final Row header = new Row(
children: <Widget>[
new Expanded(
child: new AnimatedContainer(
duration: animationDuration,
curve: Curves.fastOutSlowIn,
margin: _isChildExpanded(index)
? kExpandedEdgeInsets
: EdgeInsets.zero,
child: new SizedBox(
height: _kPanelHeaderCollapsedHeight,
child: children[index].headerBuilder(
context,
children[index].isExpanded,
),
),
),
),
new Container(
margin: const EdgeInsetsDirectional.only(end: 8.0),
child: new ExpandIcon(
isExpanded: _isChildExpanded(index),
padding: const EdgeInsets.all(16.0),
onPressed: (bool isExpanded) {
if (expansionCallback != null)
expansionCallback(index, isExpanded);
},
),
),
],
);
double _radiusValue = _isChildExpanded(index)? 8.0 : 0.0;
items.add(
new Container(
key: new _SaltedKey<BuildContext, int>(context, index * 2),
child: new Material(
elevation: 2.0,
borderRadius: new BorderRadius.all(new Radius.circular(_radiusValue)),
child: new Column(
children: <Widget>[
header,
new AnimatedCrossFade(
firstChild: new Container(height: 0.0),
secondChild: children[index].body,
firstCurve:
const Interval(0.0, 0.6, curve: Curves.fastOutSlowIn),
secondCurve:
const Interval(0.4, 1.0, curve: Curves.fastOutSlowIn),
sizeCurve: Curves.fastOutSlowIn,
crossFadeState: _isChildExpanded(index)
? CrossFadeState.showSecond
: CrossFadeState.showFirst,
duration: animationDuration,
),
],
),
),
),
);
if (_isChildExpanded(index) && index != children.length - 1)
items.add(new Divider(
key: new _SaltedKey<BuildContext, int>(context, index * 2 + 1),
height: 15.0,
));
}
return new Column(
children: items,
);
}
}
class _SaltedKey<S, V> extends LocalKey {
const _SaltedKey(this.salt, this.value);
final S salt;
final V value;
#override
bool operator ==(dynamic other) {
if (other.runtimeType != runtimeType) return false;
final _SaltedKey<S, V> typedOther = other;
return salt == typedOther.salt && value == typedOther.value;
}
#override
int get hashCode => hashValues(runtimeType, salt, value);
#override
String toString() {
final String saltString = S == String ? '<\'$salt\'>' : '<$salt>';
final String valueString = V == String ? '<\'$value\'>' : '<$value>';
return '[$saltString $valueString]';
}
}
Now use this widget in your application
import 'package:color_essence/customViews/CustomExpansionList.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class ExpansionPanelDemo extends StatefulWidget {
#override
_ExpansionPanelDemoState createState() => _ExpansionPanelDemoState();
}
class _ExpansionPanelDemoState extends State<ExpansionPanelDemo> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Expansion Panel Demo'),
),
body: Container(
padding: EdgeInsets.all(10),
child: ListView.builder(
itemCount: itemData.length,
itemBuilder: (BuildContext context, int index) {
return CustomExpansionPanelList(
animationDuration: Duration(milliseconds: 1000),
children: [
ExpansionPanel(
body: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20)),
),
padding: EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
ClipOval(
child: CircleAvatar(
child: Image.asset(
itemData[index].img,
fit: BoxFit.cover,
),
),
),
SizedBox(
height: 30,
),
Text(
itemData[index].discription,
style: TextStyle(
color: Colors.grey[700],
fontSize: 15,
letterSpacing: 0.3,
height: 1.3),
),
],
),
),
headerBuilder: (BuildContext context, bool isExpanded) {
return Container(
padding: EdgeInsets.all(10),
child: Text(
itemData[index].headerItem,
style: TextStyle(
color: itemData[index].colorsItem,
fontSize: 18,
),
),
);
},
isExpanded: itemData[index].expanded,
)
],
expansionCallback: (int item, bool status) {
setState(() {
itemData[index].expanded = !itemData[index].expanded;
});
},
);
},
),
),
);
}
List<ItemModel> itemData = <ItemModel>[
ItemModel(
headerItem: 'Android',
discription:
"Android is a mobile operating system based on a modified version of the Linux kernel and other open source software, designed primarily for touchscreen mobile devices such as smartphones and tablets. ... Some well known derivatives include Android TV for televisions and Wear OS for wearables, both developed by Google.",
colorsItem: Colors.green,
img: 'assets/images/android_img.png'
),
];
}
class ItemModel {
bool expanded;
String headerItem;
String discription;
Color colorsItem;
String img;
ItemModel({this.expanded: false, this.headerItem, this.discription,this.colorsItem,this.img});
}
Wrap the ExpansionPanelList in a ClipRRect.
ClipRRect(
borderRadius: BorderRadius.circular(8),
child: ExpansionPanelList(
children: [ExpansionPanel(body: Text('Hello World'))])
)

Update current page from widget method outside the stateful class

I have a method outside the stateful class for showing a dialog I want to refresh the data on the page after I close the dialog how it can be one? If I push the Screen again it will act weird (it will open the home page then go to the current page any idea of that it may help me to fix my issue.
AlertWidget(BuildContext context, String Fname, String Lname, String key) {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final TextEditingController _firstName = TextEditingController(text: Fname);
final TextEditingController _lastName = TextEditingController(text: Lname);
showDialog(
context: context,
builder: (context) {
var _height = MediaQuery.of(context).size.height;
var _width = MediaQuery.of(context).size.width;
return Center(
child: Material(
type: MaterialType.transparency,
child: Padding(
padding: const EdgeInsets.only(left: 15, right: 15),
child: Container(
color: Colors.white,
padding: EdgeInsets.all(15),
height: _height - _height * 11.5 / 16,
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Align(
alignment: (translator.currentLanguage == "en")
? Alignment.topLeft
: Alignment.topRight,
child: Text(
translator.translate('Name'),
style: TextStyle(
color: ProjectTheme.projectPrimaryColor,
fontSize: 25),
)),
SizedBox(
height: displayHeight(context) * 0.02,
),
Row(
children: [
Text("${translator.translate('FirstName')}:",
style: TextStyle(fontSize: 18)),
SizedBox(
height: _height * .8 / 16,
width: _width * 1.5 / 16,
),
Container(
height: _height * .5 / 16,
width: _width * 5.5 / 16,
child: Container(
child: Padding(
padding: const EdgeInsets.only(
left: 10, right: 10, top: 10),
child: TextFormField(
controller: _firstName,
validator: (value) {
if (value.trim().isEmpty)
return 'This field is required.';
return null;
},
decoration: InputDecoration(
border: InputBorder.none,
),
),
),
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.4),
spreadRadius: 2,
blurRadius: 5,
offset: Offset(0, 1),
),
],
color: Colors.white,
),
),
),
],
),
Row(
children: [
Text("${translator.translate('LastName')}:",
style: TextStyle(fontSize: 18)),
SizedBox(
height: _height * 1 / 16,
width: _width * 1.5 / 16,
),
Container(
height: _height * .5 / 16,
width: _width * 5.5 / 16,
child: Container(
child: Padding(
padding: const EdgeInsets.only(
left: 10, right: 10, top: 10),
child: TextFormField(
controller: _lastName,
validator: (value) {
if (value.trim().isEmpty)
return 'This field is required.';
return null;
},
decoration: InputDecoration(
border: InputBorder.none,
),
),
),
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.4),
spreadRadius: 2,
blurRadius: 5,
offset: Offset(0, 1),
),
],
color: Colors.white,
),
),
),
],
),
SizedBox(height: _height * .3 / 16),
Align(
alignment: Alignment.bottomRight,
child: Container(
height: 35,
width: 100,
decoration: BoxDecoration(
color: ProjectTheme.projectPrimaryColor,
borderRadius:
BorderRadius.all(Radius.circular(20.0)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 2,
blurRadius: 10,
offset: Offset(0, 3),
),
],
),
child: Center(
child: TextButton(
onPressed: () async {
bool isChanged = !(_firstName.text == Fname &&
_lastName == Lname);
if (_formKey.currentState.validate()) {
final FirebaseAuth _firebaseAuth =
FirebaseAuth.instance;
await FirebaseFirestore.instance
.collection('users')
.doc(_firebaseAuth.currentUser.uid)
.update((key == 'name')
? {
'firstName':
_firstName.text.trim(),
'lastName': _lastName.text.trim(),
'fullName':
_firstName.text.trim() +
' ' +
_lastName.text.trim(),
'userName':
_firstName.text.trim() +
' ' +
_lastName.text.trim(),
}
: {
key: _firstName.text.trim() +
' ' +
_lastName.text.trim()
});
FirebaseFirestore.instance
.collection('users')
.doc(_firebaseAuth.currentUser.uid)
.get()
.then((value) {
UserData newUser = UserData(
.......
);
Provider.of<AppData>(context, listen: false)
.updateUser(newUser);
// Navigator.of(context).pushReplacement(
// MaterialPageRoute(
// builder: (ctx) => profileScreen()));
});
}
},
child: Text(
translator.translate('Save'),
style: TextStyle(
fontSize: 16, color: Colors.white),
),
),
),
),
),
],
),
),
),
)),
);
},
);
}
Sorry for the long code, I'm trying to get much info as I can if you need more let me know.
Thanks.
The showDialog function, returns a future that can be used to see when the dialog is closed. Return this future to the page and await it or call then on it to know when it is done.
import 'package:flutter/material.dart';
Future<void> AlertWidget(
BuildContext context,
String Fname,
String Lname,
String key,
) {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final TextEditingController _firstName = TextEditingController(text: Fname);
final TextEditingController _lastName = TextEditingController(text: Lname);
return showDialog(
context: context,
builder: (context) {
/*...*/
});
}
class MyPage extends StatefulWidget {
#override
_MyPageState createState() => _MyPageState();
}
class _MyPageState extends State<MyPage> {
// this function opens the alert dialog & calls setState when the dialog is closed
void showDialogOnTap() {
// show dialog
AlertWidget(context, 'Fname', 'Lname', 'Pkey')
.then((_) { // then on closed
setState(() {}); // set page state
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(),
floatingActionButton: FloatingActionButton(
onPressed: showDialogOnTap,
),
);
}
}

Is it possible to implement widgets using list in flutter?

I am creating a Journal mobile application which would work as a medium to view magazines and daily news updates. This is my first flutter project and I am totally new to flutter. So kindly excuse me if I had said something wrong about something or didnt provide enough information.
I used a code from github for the main page of my application and made few changes to accommodate my needs. Now in my code, the home page consists of a side menu bar and this bar consists of 4 buttons, namely Home, My Profile, Premium and FAQ. The GlobalKeys for the side menu bar is called using a list by the name _keys which is of the type GlobalKey. I tried changing the data type of the list _keys to Widget and then called the corresponding Widgets of the classes. But then two errors popped out.
The getter 'currentContext' isn't defined for the class 'Widget'.
The argument type 'Widget' can't be assigned to the parameter type 'GlobalKey<State>'.
Now I would like the list _keys to be of the type Widget in order for me to call upon it's corresponding widgets of Home, My Profile, Premium and FAQ from each of it's classes in order for me to view the corresponding pages. Or if it is not possible, I would love to know an alternative for it to start working.
Following is the code of my application.
import 'dart:math' as math;
import 'package:flutter/scheduler.dart';
import 'package:google_signin_example/google%20sign%20in/logged_in_widget.dart';
import 'package:google_signin_example/main app/lib/ui_3/TravelBean.dart';
import 'package:google_signin_example/main app/lib/ui_3/magazine/screens/home_screen.dart';
import 'package:google_signin_example/main%20app/lib/ui_3/FAQ/faq.dart';
import 'package:google_signin_example/main%20app/lib/ui_3/Newspaper%20and%20Kiddos/lib_kiddos/main.dart';
import 'package:google_signin_example/main%20app/lib/ui_3/Newspaper%20and%20Kiddos/lib_news/main.dart';
import 'package:google_signin_example/main%20app/lib/ui_3/premium/premium.dart';
import 'package:google_signin_example/widget/sign_up_widget.dart';
import 'detail_page.dart';
class HomePage1 extends StatefulWidget {
#override
_HomePage1State createState() => _HomePage1State();
}
class _HomePage1State extends State<HomePage1> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Container(
child: Row(
children: <Widget>[
LeftWidget(),
Expanded(
child: RightWidget(),
)
],
),
),
);
}
}
class LeftWidget extends StatefulWidget {
#override
_LeftWidgetState createState() => _LeftWidgetState();
}
class _LeftWidgetState extends State<LeftWidget> with TickerProviderStateMixin {
List<String> _list = ["Home", "My profile", "Premium", "FAQ"];
List <Widget> _keys = [
HomePage1(), //These are the widgets from different classes.
LoggedInWidget(),
premium(),
faq(),
/*GlobalKey(), //This was available before I made the changes.
GlobalKey(),
GlobalKey(),
GlobalKey()*/
];
int checkIndex = 0;
Offset checkedPositionOffset = Offset(0, 0);
Offset lastCheckOffset = Offset(0, 0);
Offset animationOffset = Offset(0, 0);
Animation _animation;
AnimationController _animationController;
#override
void initState() {
checkIndex = _list.length - 1;
super.initState();
SchedulerBinding.instance.endOfFrame.then((value) {
calcuteCheckOffset();
addAnimation();
});
}
void calcuteCheckOffset() {
lastCheckOffset = checkedPositionOffset;
RenderBox renderBox = _keys[checkIndex].currentContext.findRenderObject(); //This is where the first error occurs.
Offset widgetOffset = renderBox.localToGlobal(Offset(0, 0));
Size widgetSise = renderBox.size;
checkedPositionOffset = Offset(widgetOffset.dx + widgetSise.width,
widgetOffset.dy + widgetSise.height);
}
#override
Widget build(BuildContext context) {
return Container(
child: Stack(
children: <Widget>[
Container(
width: 50,
decoration: BoxDecoration(
color: Color(0xff000000),
borderRadius: BorderRadius.circular(30),
),
child: Column(
children: _buildList(),
),
),
Positioned(
top: animationOffset.dy,
left: animationOffset.dx,
child: CustomPaint(
painter: CheckPointPainter(Offset(10, 0)),
),
)
],
),
);
}
List<Widget> _buildList() {
List<Widget> _widget_list = [];
_widget_list.add(Padding(
padding: EdgeInsets.only(
top: 50,
),
child: Icon(
Icons.settings,
color: Colors.white,
size: 30,
),
));
for (int i = 0; i < _list.length; i++) {
_widget_list.add(Expanded(
child: GestureDetector(
onTap: () {
indexChecked(i);
},
child: VerticalText(
_list[i],
_keys[i], //This is where the second error occurs.
checkIndex == i &&
(_animationController != null &&
_animationController.isCompleted))),
));
}
_widget_list.add(Padding(
padding: EdgeInsets.only(
top: 50,
bottom: 50,
),
child: Image(image: AssetImage('assets/images/Voix.png')),
));
return _widget_list;
}
void indexChecked(int i) {
if (checkIndex == i) return;
setState(() {
checkIndex = i;
calcuteCheckOffset();
addAnimation();
});
}
void addAnimation() {
_animationController =
AnimationController(duration: Duration(milliseconds: 300), vsync: this)
..addListener(() {
setState(() {
animationOffset =
Offset(checkedPositionOffset.dx, _animation.value);
});
});
_animation = Tween(begin: lastCheckOffset.dy, end: checkedPositionOffset.dy)
.animate(CurvedAnimation(
parent: _animationController, curve: Curves.easeInOutBack));
_animationController.forward();
}
}
class CheckPointPainter extends CustomPainter {
double pointRadius = 5;
double radius = 30;
Offset offset;
CheckPointPainter(this.offset);
#override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()..style = PaintingStyle.fill;
double startAngle = -math.pi / 2;
double sweepAngle = math.pi;
paint.color = Color(0xff000000);
canvas.drawArc(
Rect.fromCircle(center: Offset(offset.dx, offset.dy), radius: radius),
startAngle,
sweepAngle,
false,
paint);
paint.color = Color(0xffffffff);
canvas.drawCircle(
Offset(offset.dx - pointRadius / 2, offset.dy - pointRadius / 2),
pointRadius,
paint);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
class VerticalText extends StatelessWidget {
String name;
bool checked;
GlobalKey globalKey;
VerticalText(this.name, this.globalKey, this.checked);
#override
Widget build(BuildContext context) {
return RotatedBox(
key: globalKey,
quarterTurns: 3,
child: Text(
name,
style: TextStyle(
color: checked ? Color(0xffffffff) : Colors.grey,
fontSize: 16,
),
),
);
}
}
class RightWidget extends StatefulWidget {
#override
_RightWidgetState createState() => _RightWidgetState();
}
class _RightWidgetState extends State<RightWidget>
with TickerProviderStateMixin {
TabController _tabController;
#override
void initState() {
super.initState();
_tabController = TabController(vsync: this, length: 5);
}
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(
left: 15,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 50, left: 20),
child: Text(
"Voix Home",
style: TextStyle(
color: Colors.black,
fontSize: 25,
),
),
),
Padding(
padding: const EdgeInsets.only(top: 15, left: 10),
child: SizedBox(
height: 30,
child: TabBar(
isScrollable: true,
unselectedLabelColor: Colors.black,
labelColor: Color(0xffffffff),
controller: _tabController,
indicator: BoxDecoration(
color: Color(0xff9e9e9e),
borderRadius: BorderRadius.only(
topRight: Radius.circular(20),
bottomLeft: Radius.circular(20),
),
),
tabs: <Widget>[
Tab(
text: "Flash",
),
Tab(
text: "Magazine",
),
Tab(
text: "Newspaper",
),
Tab(
text: "Kiddos",
),
Tab(
text: "Editorial",
),
],
),
),
),
Expanded(
child: TabBarView(
controller: _tabController,
children: <Widget>[
TravelWidget(),
HomeScreen(),
News(),
Kiddos(),
RightBody(),
// RightBody(),
],
),
)
],
),
);
}
}
class RightBody extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(
left: 15,
),
color: Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(
top: 20,
),
child: Text(
"Flash!",
style: TextStyle(
color: Colors.black,
fontSize: 20,
),
),
),
Expanded(
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Container(
width: 220,
margin: EdgeInsets.symmetric(
horizontal: 10,
vertical: 10,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(40),
image: new DecorationImage(
image: new AssetImage('assets/images/bottom1.jpg'),
fit: BoxFit.cover,
),
boxShadow: [
BoxShadow(
spreadRadius: 5,
blurRadius: 5,
offset: Offset(1, 2),
color: Color(0x33757575),
),
],
),
),
Container(
width: 220,
margin: EdgeInsets.symmetric(
horizontal: 10,
vertical: 10,
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(40),
boxShadow: [
BoxShadow(
spreadRadius: 5,
blurRadius: 5,
offset: Offset(1, 2),
color: Color(0x33757575),
),
],
),
),
],
),
),
],
),
);
}
}
class TravelWidget extends StatelessWidget {
List<TravelBean> _list = TravelBean.generateTravelBean();
#override
Widget build(BuildContext context) {
return PageView.builder(
controller: PageController(viewportFraction: 0.9),
itemBuilder: (context, index) {
var bean = _list[index];
return GestureDetector(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return DetailPage(bean);
}));
},
child: Hero(
tag: bean.url,
child: Stack(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 30, right: 10),
child: ClipRRect(
borderRadius: BorderRadius.circular(5),
child: Image.asset(
bean.url,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover,
),
),
),
Positioned(
bottom: 80,
left: 15,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Material(
color: Colors.transparent,
child: Text(
bean.location,
style: TextStyle(
color: Colors.black54,
fontSize: 15,
),
),
),
Material(
color: Colors.transparent,
child: Text(
bean.name,
style: TextStyle(
color: Colors.black,
fontSize: 20,
),
),
),
],
),
),
Positioned(
bottom: 0,
right: 30,
child: Container(
width: 60,
height: 60,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(30),
),
child: Icon(
Icons.arrow_forward,
color: Colors.white,
size: 30,
),
),
)
],
),
),
);
},
itemCount: _list.length,
);
}
}
At the beginning, when I leave the list _keys to be of the type GlobalKey and don't comment out the following 4 GlobalKeys I get the output but the side menu bar won't work.
This is my application with GlobalKeys in place of those Widgets
I want those corresponding pages to display when clicked on. But that render object just switches between the options and the same page is displayed.
So kindly help me out.
PS : As said earlier I'm new to flutter, so kindly don't mistake me if I had something wrong.
I suggest you check about flutter state management, especially Mobx with Provider, it will be kind easier for you.

why unnecessary values overriding when calculating total in flutter

when i try to increase the quantity the total amount showing big numbers and when i exit the page and reenter it showing correct out put why this happenning...?this happens when i increase or decrease the quantity
this happens when i exit the page and reenter
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:appnew/src/hivedatabase/cart_model.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:appnew/src/widgets/totalprice.dart';
List<String> compnme = List();
List<String> compqnt = List();
class CartPage extends StatefulWidget {
#override
_CartPageState createState() => _CartPageState();
}
class _CartPageState extends State<CartPage> {
double sum = 0;
final cartBox = Hive.box('carts');
final totBox = Hive.box('tot');
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 1,
backgroundColor: Colors.lightGreen,
title: Text(
'Cart',
),
),
body: _buildListView(),
bottomNavigationBar: Container(
color: Colors.white,
child: Row(
children: <Widget>[
Expanded(
child: _buildtotal(),
),
Expanded(
child: new MaterialButton(
onPressed: () {
final cartBox = Hive.box('carts');
cartBox.clear();
compnme.clear();
compqnt.clear();
totBox.clear();
},
child: new Text(
"Check Out",
style: TextStyle(color: Colors.white),
),
color: Colors.red,
)),
],
),
),
);
}
Widget _buildListView() {
// ignore: deprecated_member_use
return WatchBoxBuilder(
box: Hive.box('carts'),
builder: (context, cartBox) {
return ListView.builder(
itemCount: cartBox.length,
itemBuilder: (BuildContext context, int index) {
final cartModel = cartBox.getAt(index) as CartModel;
double iprice = double.parse(cartModel.price);
double nprice = 0;
int iquant = int.parse(cartModel.quantitys);
return Card(
elevation: 5,
child: Container(
height: 130,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
height: 129,
width: 125,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(cartModel.img),
fit: BoxFit.fill,
),
),
),
Container(
height: 130,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(0, 10, 0, 5),
child: Text(
cartModel.pname,
style: TextStyle(fontSize: 20),
),
),
Padding(
padding: EdgeInsets.fromLTRB(0, 4, 0, 3),
child: Container(
width: 160,
child: Text(cartModel.curquant,
style: TextStyle(fontSize: 17)),
),
),
Padding(
padding: EdgeInsets.fromLTRB(1, 25, 0, 0),
child: Text("Rs." + cartModel.price,
style: TextStyle(
fontSize: 19, color: Colors.black54)),
)
],
),
),
Padding(
padding: const EdgeInsets.fromLTRB(0, 77, 19, 2),
child: Container(
height: 90,
child: IconButton(
icon: Icon(Icons.add_circle,
size: 35, color: Colors.green[300]),
onPressed: () {
iquant++;
nprice = iprice + (iprice / (iquant - 1));
cartBox.putAt(
index,
CartModel(
cartModel.pname,
cartModel.curquant,
cartModel.img,
nprice.toString(),
iquant.toString()));
}),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(0, 77, 0, 2),
child: Container(
height: 90,
child: CircleAvatar(
backgroundColor: Colors.grey[300],
maxRadius: 16,
child: Text(cartModel.quantitys),
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(19, 77, 0, 2),
child: Container(
height: 90,
child: IconButton(
icon: Icon(Icons.remove_circle,
size: 35, color: Colors.redAccent),
onPressed: () {
if (iquant == 1) {
cartBox.deleteAt(index);
print(compnme[index]);
compnme.removeAt(index);
compqnt.removeAt(index);
} else {
iquant--;
nprice = iprice - (iprice / (iquant + 1));
cartBox.putAt(
index,
CartModel(
cartModel.pname,
cartModel.curquant,
cartModel.img,
nprice.toString(),
iquant.toString()));
}
}),
),
)
],
),
),
);
},
);
},
);
}
Widget _buildtotal() {
// ignore: deprecated_member_use
return WatchBoxBuilder(
box: Hive.box('carts'),
builder: (context, cartBox) {
for (int i = 0; i < cartBox.length; i++) {
final cartModel = cartBox.getAt(i) as CartModel;
double iprice = double.parse(cartModel.price);
sum += iprice;
print(sum);
}
return ListTile(
title: new Text("total:", style: TextStyle(color: Colors.black)),
subtitle: new Text(sum.toString(),
style: TextStyle(
color: Colors.black,
fontSize: 16,
)),
);
});
}
}
i tried adding setState() in buttons and functions but it didnt worked
Just assign zero each time in _buildtotal() method
Widget _buildtotal() {
sum=0;//This will reset sum value zero before re-calculating total
// ignore: deprecated_member_use
return WatchBoxBuilder(
box: Hive.box('carts'),
builder: (context, cartBox) {
for (int i = 0; i < cartBox.length; i++) {
final cartModel = cartBox.getAt(i) as CartModel;
double iprice = double.parse(cartModel.price);
sum += iprice;
print(sum);
}
return ListTile(
title: new Text("total:", style: TextStyle(color: Colors.black)),
subtitle: new Text(sum.toString(),
style: TextStyle(
color: Colors.black,
fontSize: 16,
)),
);
});
}

Categories

Resources