Flutter: Listview is scrolling on iOS but not on Android - flutter

Custom Widget Listview is scrolling properly on iOS devices but not on Andriod devices. I checked on multiple devices, the same result. I'm using the same widget in BottomSheet it works just fine on both platforms. I couldn't figure out what is the issue.
The following is the code:
UI Screen
class OnBoardingScreen extends StatelessWidget {
//
final _dataAssetController = Get.find<DataAsset>();
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
physics: NeverScrollableScrollPhysics(),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: AssetImage('images/ss.jpg'),
),
),
child: SafeArea(
child: Padding(
padding: const EdgeInsets.only(left: 15.0, top: 25.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
///---------------------- Title
Text(
'Your',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
Text(
'Star Sign?',
style: TextStyle(
fontSize: 45.0,
fontFamily: 'FredokaOne',
letterSpacing: 2.0,
color: _dataAssetController.mainColor,
),
),
SizedBox(height: 15.0),
///---------------------- Zodiac List
ZodiacListWidget(),
],
),
),
),
),
),
);
}
}
Listview Widget
class ZodiacListWidget extends StatelessWidget {
//
final _dataAssetController = Get.find<DataAsset>();
//
final _zodiacController = Get.find<ZodiacApiController>();
#override
Widget build(BuildContext context) {
return Container(
child: ListView.builder(
shrinkWrap: true,
itemCount: _dataAssetController.zodiacList.length,
itemBuilder: (BuildContext context, index) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 8.0),
child: Card(
color: Colors.grey[800],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: ListTile(
title: Padding(
padding: EdgeInsets.only(left: 16.0),
child: Text(
_dataAssetController.zodiacList[index],
style: TextStyle(
color: Colors.grey[100],
fontSize: 25.0,
fontWeight: FontWeight.bold,
),
),
),
subtitle: Padding(
padding: EdgeInsets.only(left: 15.0),
child: Text(
_dataAssetController.zodiacDateRangeList[index],
style: TextStyle(
color: Colors.grey[500],
fontSize: 18.0,
),
),
),
leading: CircleAvatar(
radius: 20.0,
backgroundColor: Colors.grey[800],
child: SvgPicture.asset(
_dataAssetController.zodiacSVGList[index],
color: _dataAssetController.mainColor,
),
),
trailing: IconButton(
icon: GetBuilder<ZodiacApiController>(
builder: (_zController) => Icon(
Icons.adjust,
size: 25.0,
color: _dataAssetController.zodiacList[index] ==
_zController.zodiacSign
? _dataAssetController.mainColor
: Colors.grey[300],
),
),
onPressed: () {
_zodiacController.changeZodiac(index);
_zodiacController.onBoarding != null
? null
: Get.defaultDialog(
title: '',
titleStyle: TextStyle(
fontSize: 0.0,
),
middleText: _zodiacController.zodiacSign!,
middleTextStyle: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
),
textConfirm: 'Confirm',
confirmTextColor: Colors.white,
onConfirm: () {
_zodiacController.onBoarding != null
? null
: _zodiacController.changeOnBoarding();
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => HomeScreen(),
),
);
},
textCancel: 'Back',
cancelTextColor: Colors.blueAccent,
onCancel: () => Navigator.pop(context),
);
},
),
),
),
);
},
),
);
}
}

Related

Flutter: I would like to scroll the ListView after the main SingleChildScrollView Scroll end

I have a ListView.builder wrapped with a SingleChildScrollView, and each has its scroll, so when I click at the ListView it only scroll the ListView without Scroll the SingleChildScrollView, and my ListView is dynamic so I can't use physics: const NeverScrollableScrollPhysics() because it disable my ListVeiw.builder
I want to Scroll the main screen which has some widgets and the ListView, builder in the middle and in last has a bottom
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
"Carrinho",
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 18,
fontFamily: 'Inter'),
),
),
body: SingleChildScrollView(
child: Column(
children: [
Stack(
children: <Widget>[
Container(
width: 400,
child: Image.asset('assets/images/cover.jpg'),
),
Center(
child: Column(
children: [
SizedBox(height: 60),
Text(
"MEU CESTO",
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 30,
fontFamily: 'Inter'),
),
],
),
),
],
),
Container(
height: 80,
padding: const EdgeInsets.all(15),
decoration: BoxDecoration(
color: sGreenColour,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10),
),
),
child: Container(
child: Column(
children: [
Row(children: [
Text(
"ITENS: ",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 16),
),
Text("$itemsQtd",
style: TextStyle(color: Colors.white, fontSize: 16))
]),
Row(children: [
Text("TOTAL: ",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 18)),
Text("$totalValue MT",
style: TextStyle(color: Colors.white, fontSize: 18))
])
],
),
),
),
Container(
height: MediaQuery.of(context).size.height,
// HERE MY ListView.buider
child: CartProducts(
cart_list: cart_list,
),
),
SizedBox(height: 40),
Container(
width: MediaQuery.of(context).size.width - 30,
child: Row(
children: [
Container(
height: 50,
width: (MediaQuery.of(context).size.width / 2) - 15,
child: ElevatedButton(
onPressed: () {},
child: Text("$totalValue MT",
style: TextStyle(color: sGreenColour)),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(
sGreenLightColour),
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.zero,
),
),
),
),
),
Container(
height: 50,
width: (MediaQuery.of(context).size.width / 2) - 15,
child: ElevatedButton(
onPressed: () {},
child: Text(
"TERMINAR",
style: TextStyle(color: Colors.white),
),
style: ButtonStyle(
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.zero,
side: BorderSide(color: sGreenColour),
),
),
),
),
)
],
),
),
SizedBox(height: 10),
],
),
));
}
}
and my ListView.builder
class _CartProductsState extends State<CartProducts> {
#override
Widget build(BuildContext context) {
return ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), // Disable Scroll
itemCount: widget.cart_list.length,
itemBuilder: (BuildContext context, int index) {
return SigleProduct(
name: widget.cart_list[index]["name"],
picture: widget.cart_list[index]["picture"],
price: widget.cart_list[index]["price"],
unit: widget.cart_list[index]["unit"],
);
});
}
}
// THE ELEMENT OF THE GRIDVIEW
class SigleProduct extends StatelessWidget {
SigleProduct({this.name, this.picture, this.price, this.unit})
: super(key: null);
final name;
final picture;
final price;
final unit;
showAlertDialog(BuildContext context, int id) {
// set up the buttons
Widget cancelButton = TextButton(
child: Text("Não"),
onPressed: () {
Navigator.of(context).pop(); // dismiss dialog
},
);
Widget continueButton = TextButton(
child: Text(
"Sim",
style: TextStyle(color: Colors.red),
),
onPressed: () {
Navigator.of(context).pop(); // dismiss dialog
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text("Producto Removido!"),
));
},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Center(child: Text("Alerta!")),
content: Text("Gostaria de Remover o producto do carrinho?"),
actions: [
cancelButton,
continueButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
#override
Widget build(BuildContext context) {
return Container(
child: Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.zero,
),
child: ListTile(
onTap: () {},
leading: Container(
width: 80,
//color: Colors.amber,
child: Image.asset(picture),
),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(name,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 14)),
Text("$price MT",
style: TextStyle(
fontWeight: FontWeight.bold,
color: sGreenColour,
fontSize: 14)),
],
),
subtitle: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Unit: $price MT/$unit',
style: TextStyle(color: Colors.black45)),
Text('Qtd: 2/$unit', style: TextStyle(color: Colors.black45)),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(
height: 25,
width: 110,
child: ElevatedButton(
onPressed: () {
showAlertDialog(context, 1);
},
child: Text(
"REMOVER",
style: TextStyle(fontSize: 10, color: Colors.white),
),
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.red)),
),
),
Container(
height: 25,
width: 110,
child: ElevatedButton(
onPressed: () {},
child: Text("ACTUALIZAR",
style:
TextStyle(fontSize: 10, color: Colors.white))),
),
],
)
],
),
selected: false,
),
),
);
}
}
Please Help

StateError was thrown building StreamBuilder<DocumentSnapshot<Object?>Bad state: cannot get a field on a DocumentSnapshotPlatform which does not exist

I am Trying to build an app. which fetching the user credential data and shows in profile page. I am getting an error => Bad state: cannot get a field on a DocumentSnapshotPlatform which does not exist in the profile section need help
Widget headerProfile(BuildContext context, DocumentSnapshot snapshot) {
return SizedBox(
height: MediaQuery.of(context).size.height * 0.25,
width: MediaQuery.of(context).size.width,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: Container(
height: 200.0,
width: 180.0,
child: Column(
children: [
GestureDetector(
onTap: () {},
child: CircleAvatar(
backgroundColor: constantColors.transperant,
radius: 60.0,
backgroundImage: NetworkImage(snapshot['userimage']),
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(snapshot['username'],
style: TextStyle(
color: constantColors.whiteColor,
fontWeight: FontWeight.bold,
fontSize: 16.0)),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(EvaIcons.email, color: constantColors.greenColor),
Padding(
padding: const EdgeInsets.only(left:9.0),
child: Text(snapshot['useremail'],
style: TextStyle(
color: constantColors.whiteColor,
fontWeight: FontWeight.bold,
fontSize: 13.0)),
),
],
),
),
],
),
),
),
Container(
// width: 200.0,
width: 200.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(top:16.0, right: 30.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
decoration: BoxDecoration(
color: constantColors.darkColor,
borderRadius: BorderRadius.circular(15.0)),
height: 70.0,
width: 80.0,
child: Column(
children: [
Text(
'0',
style: TextStyle(
color: constantColors.whiteColor,
fontWeight: FontWeight.bold,
fontSize: 28.0),
),
Text(
'Followers',
style: TextStyle(
color: constantColors.whiteColor,
fontWeight: FontWeight.bold,
fontSize: 12.0),
),
],
),
),
Container(
decoration: BoxDecoration(
color: constantColors.darkColor,
borderRadius: BorderRadius.circular(15.0)),
height: 70.0,
width: 80.0,
child: Column(
children: [
Text(
'0',
style: TextStyle(
color: constantColors.whiteColor,
fontWeight: FontWeight.bold,
fontSize: 28.0),
),
Text(
'Following',
style: TextStyle(
color: constantColors.whiteColor,
fontWeight: FontWeight.bold,
fontSize: 12.0),
),
],
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(top:16.0),
child: Container(
decoration: BoxDecoration(
color: constantColors.darkColor,
borderRadius: BorderRadius.circular(15.0)),
height: 70.0,
width: 80.0,
child: Column(
children: [
Text(
'0',
style: TextStyle(
color: constantColors.whiteColor,
fontWeight: FontWeight.bold,
fontSize: 28.0),
),
Text(
'Posts',
style: TextStyle(
color: constantColors.whiteColor,
fontWeight: FontWeight.bold,
fontSize: 12.0),
),
],
),
),
),
],
),
)
],
),
);
}
I think the error is coming from the snapshot['username'], snapshot['userimage'] and snapshot['useremail'].....
This is my Profile.dart
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
leading: IconButton(
onPressed: () {},
icon: Icon(
EvaIcons.settings2Outline,
color: constantColors.lightBlueColor,
)),
actions: [
IconButton(
onPressed: () {},
icon: Icon(EvaIcons.logOutOutline,
color: constantColors.greenColor)),
],
backgroundColor: constantColors.blueGreyColor.withOpacity(0.4),
title: RichText(
text: TextSpan(
text: 'My ',
style: TextStyle(
color: constantColors.whiteColor,
fontWeight: FontWeight.bold,
fontSize: 20.0,
),
children: <TextSpan>[
TextSpan(
text: 'Profile',
style: TextStyle(
color: constantColors.blueColor,
fontWeight: FontWeight.bold,
fontSize: 20.0,
),
),
])),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: StreamBuilder<DocumentSnapshot>(
stream: FirebaseFirestore.instance
.collection('users')
.doc(Provider.of<Authentication>(context, listen: false)
.getUserUid)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return new Column(
children: [
Provider.of<ProfileHelpers>(context, listen: false).headerProfile(context, snapshot.data)
],
);
}
},
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: constantColors.blueGreyColor.withOpacity(0.6)),
),
),
),
);
}
and below is the FirebaseOperations.dart
Future initUserData(BuildContext context) async {
return FirebaseFirestore.instance
.collection('users')
.doc(Provider.of<Authentication>(context, listen: false).getUserUid)
.get()
.then((doc) {
print('Fetching user data...');
initUserName = doc.data()['username'];
initUserEmail = doc.data()['useremail'];
initUserImage = doc.data()['userimage'];
print(initUserName);
print(initUserEmail);
print(initUserImage);
notifyListeners();
});
String initUserEmail, initUserName, initUserImage;
String get getInitUserName => initUserName;
String get getInitUserEmail => initUserEmail;
String get getInitUserImage => initUserImage;
All my code is this please help and there is user profile circle avatar at the bottom navbar it is also not the the image
Widget bottomNavBar(BuildContext context, int index, PageController pageController) {
return CustomNavigationBar(
currentIndex: index,
bubbleCurve: Curves.bounceIn,
scaleCurve: Curves.decelerate,
selectedColor: constantColors.blueColor,
unSelectedColor: constantColors.whiteColor,
strokeColor: constantColors.blueColor,
scaleFactor: 0.5,
iconSize: 30.0,
onTap: (val) {
index = val;
pageController.jumpToPage(val);
notifyListeners();
},
backgroundColor: Color(0xff040307),
items: [
CustomNavigationBarItem(icon: Icon(EvaIcons.home)),
CustomNavigationBarItem(icon: Icon(Icons.message_rounded)),
CustomNavigationBarItem(
icon: CircleAvatar(
radius: 35.0,
backgroundColor: constantColors.blueGreyColor,
backgroundImage: NetworkImage(Provider.of<FirebaseOperations>(context, listen: false).initUserImage),
)),
]);
}
Homepage.dart
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: constantColors.darkColor,
body: PageView(
controller: homepageController,
children: [
Feed(),
Chatroom(),
Profile(),
],
physics: NeverScrollableScrollPhysics(),
onPageChanged: (page) {
setState(() {
pageIndex = page;
});
},
),
bottomNavigationBar: Provider.of<HomepageHelpers>(context, listen: false)
.bottomNavBar(context, pageIndex, homepageController),
);
}
Please Help

Black Screen when I click on Navigator.pop()

So I have this app I want it to open a new page when I click on a button. It was working before when my second page is a stateless widget. But when I changed it to Stateful Widget , and clicked on the button , my entire screen turns black.
Problem :
The Problem (PICTURE)
And here is my code :
class _MainBodyState extends State<MainBody> {
Color lol = Colors.red;
showMsg(msg) {
return ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(msg.toString()),
),
);
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(10),
child: SingleChildScrollView(
child: Column(
children: [
Text(
"Welcome to",
style: TextStyle(
fontSize: 35,
fontWeight: FontWeight.bold,
),
),
Text(
"I d k what it is tbh",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.grey,
),
),
Divider(
color: Colors.black,
thickness: 1,
),
Padding(
padding: const EdgeInsets.all(10),
child: Card(
semanticContainer: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Container(
child: Image.asset(
'assets/images/3.jpg',
alignment: Alignment.bottomCenter,
fit: BoxFit.cover,
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
elevation: 8,
),
),
Divider(
color: Colors.black,
thickness: 1,
),
Padding(
padding: const EdgeInsets.only(bottom: 10, top: 10),
child: Text(
"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
textAlign: TextAlign.justify,
style: TextStyle(
fontSize: 20,
letterSpacing: 1.4,
height: 1.4,
),
),
),
Divider(
color: Colors.black,
thickness: 1,
),
Text(
"Images",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
for (int i = 1; i <= 3; i++)
GestureDetector(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(10),
child: Card(
semanticContainer: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Container(
width: 200,
height: 200,
color: Colors.accents[i],
child: Image.asset(
"assets/images/$i.jpg",
alignment: Alignment.bottomCenter,
fit: BoxFit.cover,
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
elevation: 5,
),
),
Padding(
padding: const EdgeInsets.only(top: 5, bottom: 5),
child: Center(
child: Text(
i.toString(),
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
),
],
),
),
Divider(
color: Colors.black,
thickness: 1,
),
TextButton(
child: Text(
"CLICK FOR MAGIK",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
onPressed: () {
setState(() {
lol = Color(Random().nextInt(0xffffffff));
});
},
style: TextButton.styleFrom(
backgroundColor: lol,
),
),
TextButton(
child: Text(
"CLICK FOR NEW PAGE",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
onPressed: () {
showMsg("Open new page");
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()), <== The Open Second Page
);
},
style: TextButton.styleFrom(
backgroundColor: Colors.red,
),
),
Divider(
color: Colors.black,
thickness: 1,
),
],
),
),
);
}
}
And This is my Second Screen code :
class SecondRoute extends StatefulWidget {
#override
_SecondRouteState createState() => _SecondRouteState();
}
class _SecondRouteState extends State<SecondRoute> {
#override
Widget build(BuildContext context) {
return Container(
child: SingleChildScrollView(
child: Column(
children: <Widget>[
ElevatedButton(
onPressed: () {
// Navigate back to first route when tapped.
Navigator.pop(context);
},
child: Text('Go back!'),
),
],
),
),
);
}
}
Both of my widget is Stateful ( Before that my second widget was Stateless and it works fine )
Any help is appreciated , thanks !
UPDATE : When I change my second widget back to stateless , It shows black screen and isn't working either

Pass snapshot data to Flutter Widget

I am trying to pass from data from snapshot through to a Widget so I can render out the data but I am getting the following error
lib/screens/RetailerList.dart:215:35: Error: Too few positional arguments: 1 required, 0 given.
? _buildRetailer(retailer: snapshot.data)
Widgets
Widget _buildRetailer(Retailer retailer) {
return GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
// builder: (_) => RetailerDetails(retailer: retailer[0]),
),
);
},
child: Padding(
padding: EdgeInsets.only(left: 40.0, bottom: 30.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Hero(
tag: retailer.slug,
child: Container(
width: double.infinity,
height: 250.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0),
bottomLeft: Radius.circular(20.0),
),
image: DecorationImage(
image: NetworkImage(
"https://site-assets.afterpay.com/assets/favicon/apple-touch-icon-47062a004c5b1440ea8159b43580154540d76df61dc55dc87522378f8f76bbec.png",
),
fit: BoxFit.cover,
),
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(12.0, 12.0, 40.0, 0.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
retailer.name,
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 24.0,
fontWeight: FontWeight.bold,
),
),
IconButton(
icon: Icon(Icons.favorite_border),
iconSize: 30.0,
color: Color(0xFFFD6456),
onPressed: () => print('Favorite'),
),
],
),
),
Padding(
padding: EdgeInsets.fromLTRB(12.0, 0.0, 40.0, 12.0),
child: Text(
retailer.shortDescription,
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 16.0,
color: Colors.grey,
),
),
),
],
),
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: Theme.of(context).platform == TargetPlatform.iOS
? CupertinoNavigationBar(
actionsForegroundColor: Color.fromRGBO(108, 212, 196, 1),
middle: Text('Explore Retailers',
style: GoogleFonts.nunito(
fontWeight: FontWeight.w700,
textStyle: TextStyle(
color: Color.fromRGBO(98, 49, 158, 1),
letterSpacing: .5,
fontSize: 20))),
leading: IconButton(
tooltip: 'Filter Retailers',
icon: Icon(IconData(0xF4A6,
fontFamily: CupertinoIcons.iconFont,
fontPackage: CupertinoIcons.iconFontPackage)),
// onPressed: _onButtonPressed
),
)
: AppBar(
title: Text('Explore Retailers',
style: GoogleFonts.nunito(fontWeight: FontWeight.w700)),
actions: <Widget>[
IconButton(
tooltip: 'Filter Retailers',
icon: Icon(Icons.filter_list),
// onPressed: _onButtonPressed
)
],
),
backgroundColor: Colors.white,
body: ListView(
children: <Widget>[
SizedBox(height: 10.0),
Container(height: 100.0, child: _buildListView()),
SizedBox(height: 50.0),
StreamBuilder<List<Retailer>>(
stream: fetchRetailers().asStream(),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? _buildRetailer(retailer: snapshot.data)
: Center(child: CircularProgressIndicator());
},
)
],
),
);
}
}
Instead of buildRetailer(retailer: snapshot.data)
Do buildRetailer(snapshot.data)
Since you're passing the data to the named parameter retailer which doesn't exist, as you have defined positional parameter in your buildRetailer method

Flutter: Updating UI from outside of a StatefulWidget

I am new to flutter, and working on a shopping cart project. i don't know how exatly i am suppose to ask this question but, here is what i wanted.
I am trying to update my UI when the cart item and prices changes, which means to display sum amount of products from ListView (Stateful widget) to main OrderPage Stateful widget. I know about setState() method, but i think i should use some callback methods here, dont know exactly.
I have explained in short in Image - see below img
What i have done: when user modify cart products, I have saved the value (price/product/count) in to constant value , i calculate the value and save in constant value, and later use that const var in Main widget (Main Ui), which does update when i close and reopen the page, but could not able to update when button pressed (product +/-buttons)
What i want to do is,
Update my total value when +/- buttons are pressed.
Here is my full code:
class cartConstant{
static int packageCount;
static List<int> list;
}
class OrderPage extends StatefulWidget {
#override
_OrderPageState createState() => _OrderPageState();
}
class _OrderPageState extends State<OrderPage> {
int data = 3;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
automaticallyImplyLeading: true,
iconTheme: IconThemeData(
color: Colors.black54, //change your color here
),
backgroundColor: Colors.white,
elevation: 1,
title: Text("Your order Summery",style: TextStyle(color: Colors.black54),),
centerTitle: true,
),
body: Container(
child:
FutureBuilder(
builder: (context, snapshot){
// var datas = snapshot.data;
return
ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: data,
itemBuilder: (BuildContext context, int index){
// Cart cart = datas[index];
return CartListView();
},
padding: EdgeInsets.symmetric(horizontal: 10.0),
scrollDirection: Axis.vertical,
);
},
),
),
bottomNavigationBar: _buildTotalContainer(),
);
}
Widget _buildTotalContainer() {
return Container(
height: 220.0,
padding: EdgeInsets.only(
left: 10.0,
right: 10.0,
),
child: Column(
children: <Widget>[
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(top: 10),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Subtotal",
style: TextStyle(
color: Color(0xFF9BA7C6),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
Text(
cartConstant.packageCount.toString(),
style: TextStyle(
color: Color(0xFF6C6D6D),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
],
),
),
SizedBox(
height: 15,
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Discount",
style: TextStyle(
color: Color(0xFF9BA7C6),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
Text(
"0.0",
style: TextStyle(
color: Color(0xFF6C6D6D),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
],
),
SizedBox(
height: 10.0,
),
Divider(
height: 2.0,
),
SizedBox(
height: 20.0,
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Cart Total",
style: TextStyle(
color: Color(0xFF9BA7C6),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
Text(
cartConstant.packageCount.toString(),
style: TextStyle(
color: Color(0xFF6C6D6D),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
],
),
SizedBox(
height: 20.0,
),
GestureDetector(
onTap: () {
// Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => SignInPage()));
},
child: Container(
height: 50.0,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(35.0),
),
child: Center(
child: Text(
"Proceed To Checkout",
style: TextStyle(
color: Colors.white,
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
),
),
),
),
SizedBox(
height: 20.0,
),
],
),
);
}
}
class CartListView extends StatefulWidget {
#override
_CartListViewState createState() => _CartListViewState();
}
class _CartListViewState extends State<CartListView> {
int _counter = 1;
int getPrice(int i,int priceC){
cartConstant.packageCount = i*priceC;
return cartConstant.packageCount;
}
#override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 15.0, vertical: 15.0),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
decoration: BoxDecoration(
border: Border.all(color: Color(0xFFD3D3D3), width: 2.0),
borderRadius: BorderRadius.circular(10.0),
),
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 10.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
InkWell(
onTap: (){
setState(() {
_counter++;
if (_counter > 20) {
_counter = 20;
}
});
},
child: Icon(Icons.add, color: Color(0xFFD3D3D3))),
Text(
"$_counter",
style: TextStyle(fontSize: 18.0, color: Colors.grey),
),
InkWell(
onTap:(){
setState(() {
_counter--;
if (_counter < 2) {
_counter = 1;
}
});
},
child: Icon(Icons.remove, color: Color(0xFFD3D3D3))),
],
),
),
),
SizedBox(
width: 20.0,
),
Container(
height: 70.0,
width: 70.0,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/food.jpg"),
fit: BoxFit.cover),
borderRadius: BorderRadius.circular(35.0),
boxShadow: [
BoxShadow(
color: Colors.black54,
blurRadius: 5.0,
offset: Offset(0.0, 2.0))
]),
),
SizedBox(
width: 20.0,
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Employee Package",
style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold),
),
SizedBox(height: 5.0),
SizedBox(height: 5.0),
Container(
height: 25.0,
width: 120.0,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Row(
children: <Widget>[
Text("Price",
style: TextStyle(
color: Color(0xFFD3D3D3),
fontWeight: FontWeight.bold)),
SizedBox(
width: 5.0,
),
InkWell(
onTap: () {},
child: Text(
getPrice(_counter, 2000).toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.red,
),
),
),
SizedBox(
width: 10.0,
),
],
),
],
),
),
],
),
Spacer(),
GestureDetector(
onTap: () {
},
child: Icon(
Icons.cancel,
color: Colors.grey,
),
),
],
),
),
);
}
}
you can also check from my cart screen shot below:
You can copy paste run full code below
You can use callback refresh() and pass callback to CartListView
code snippet
class _OrderPageState extends State<OrderPage> {
int data = 3;
void refresh() {
setState(() {});
}
...
itemBuilder: (BuildContext context, int index) {
// Cart cart = datas[index];
return CartListView(refresh);
},
...
class CartListView extends StatefulWidget {
VoidCallback callback;
CartListView(this.callback);
...
InkWell(
onTap: () {
setState(() {
_counter++;
if (_counter > 20) {
_counter = 20;
}
});
widget.callback();
},
working demo
full code
import 'package:flutter/material.dart';
class cartConstant {
static int packageCount;
static List<int> list;
}
class OrderPage extends StatefulWidget {
#override
_OrderPageState createState() => _OrderPageState();
}
class _OrderPageState extends State<OrderPage> {
int data = 3;
void refresh() {
setState(() {});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
automaticallyImplyLeading: true,
iconTheme: IconThemeData(
color: Colors.black54, //change your color here
),
backgroundColor: Colors.white,
elevation: 1,
title: Text(
"Your order Summery",
style: TextStyle(color: Colors.black54),
),
centerTitle: true,
),
body: Container(
child: FutureBuilder(
builder: (context, snapshot) {
// var datas = snapshot.data;
return ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: data,
itemBuilder: (BuildContext context, int index) {
// Cart cart = datas[index];
return CartListView(refresh);
},
padding: EdgeInsets.symmetric(horizontal: 10.0),
scrollDirection: Axis.vertical,
);
},
),
),
bottomNavigationBar: _buildTotalContainer(),
);
}
Widget _buildTotalContainer() {
return Container(
height: 220.0,
padding: EdgeInsets.only(
left: 10.0,
right: 10.0,
),
child: Column(
children: <Widget>[
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(top: 10),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Subtotal",
style: TextStyle(
color: Color(0xFF9BA7C6),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
Text(
cartConstant.packageCount.toString(),
style: TextStyle(
color: Color(0xFF6C6D6D),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
],
),
),
SizedBox(
height: 15,
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Discount",
style: TextStyle(
color: Color(0xFF9BA7C6),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
Text(
"0.0",
style: TextStyle(
color: Color(0xFF6C6D6D),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
],
),
SizedBox(
height: 10.0,
),
Divider(
height: 2.0,
),
SizedBox(
height: 20.0,
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Cart Total",
style: TextStyle(
color: Color(0xFF9BA7C6),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
Text(
"8000",
style: TextStyle(
color: Color(0xFF6C6D6D),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
],
),
SizedBox(
height: 20.0,
),
GestureDetector(
onTap: () {
// Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => SignInPage()));
},
child: Container(
height: 50.0,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(35.0),
),
child: Center(
child: Text(
"Proceed To Checkout",
style: TextStyle(
color: Colors.white,
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
),
),
),
),
SizedBox(
height: 20.0,
),
],
),
);
}
}
class CartListView extends StatefulWidget {
VoidCallback callback;
CartListView(this.callback);
#override
_CartListViewState createState() => _CartListViewState();
}
class _CartListViewState extends State<CartListView> {
int _counter = 1;
int getPrice(int i, int priceC) {
cartConstant.packageCount = i * priceC;
return cartConstant.packageCount;
}
#override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 15.0, vertical: 15.0),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
decoration: BoxDecoration(
border: Border.all(color: Color(0xFFD3D3D3), width: 2.0),
borderRadius: BorderRadius.circular(10.0),
),
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 10.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
InkWell(
onTap: () {
setState(() {
_counter++;
if (_counter > 20) {
_counter = 20;
}
});
widget.callback();
},
child: Icon(Icons.add, color: Color(0xFFD3D3D3))),
Text(
"$_counter",
style: TextStyle(fontSize: 18.0, color: Colors.grey),
),
InkWell(
onTap: () {
setState(() {
_counter--;
if (_counter < 2) {
_counter = 1;
}
});
widget.callback();
},
child: Icon(Icons.remove, color: Color(0xFFD3D3D3))),
],
),
),
),
SizedBox(
width: 20.0,
),
Container(
height: 70.0,
width: 70.0,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/food.jpg"),
fit: BoxFit.cover),
borderRadius: BorderRadius.circular(35.0),
boxShadow: [
BoxShadow(
color: Colors.black54,
blurRadius: 5.0,
offset: Offset(0.0, 2.0))
]),
),
SizedBox(
width: 20.0,
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Employee Package",
style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold),
),
SizedBox(height: 5.0),
SizedBox(height: 5.0),
Container(
height: 25.0,
width: 120.0,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Row(
children: <Widget>[
Text("Price",
style: TextStyle(
color: Color(0xFFD3D3D3),
fontWeight: FontWeight.bold)),
SizedBox(
width: 5.0,
),
InkWell(
onTap: () {},
child: Text(
getPrice(_counter, 2000).toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.red,
),
),
),
SizedBox(
width: 10.0,
),
],
),
],
),
),
],
),
Spacer(),
GestureDetector(
onTap: () {},
child: Icon(
Icons.cancel,
color: Colors.grey,
),
),
],
),
),
);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: OrderPage(),
);
}
}
When the button is tapped, you just need to update the Subtotal amount and cart total.
Step 1 : Replace the harcoded value by a variable. So, something like :
Row(
children: <Widget>[
Text(
"Subtotal",
style: ...
),
Text(
"$subTotal",
style: ....
),
],
),
Step 2 : Now, add a code to calcualte subTotal and cartTotal. You already have code which increments and decrements the variable _counter. You just need to tweak that part like :
setState( (){
_counter++;
// So, the quantity is increased. Just get the price of current item and add in the sub total.
subTotal += priceC;
cartTotal = subTotal - discount;
} );