Flutter: My Listview.builder disappears under my Fixed bottom Container
742
Solution 1
Please check the edited code here.
class CheckoutScreen extends StatelessWidget {
static const String id = 'checkout_screen';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(
Icons.arrow_back_ios,
color: Colors.black26,
),
onPressed: () => Navigator.pop(context),
),
title: Text(
'Shopping cart',
style: TextStyle(
fontSize: 21.0,
color: Colors.black26,
fontWeight: FontWeight.bold,
),
),
elevation: 0.0,
backgroundColor: Colors.white,
),
// bottomNavigationBar: _buildCartSummary(context),
body: Column(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height - 225,
child: ListView.builder(
shrinkWrap: true,
itemCount: 6,
itemBuilder: (context, index) {
return _buildCartItems();
},
),
),
Expanded(
// height: 300,
// color: Colors.white,
child: Align(
alignment: Alignment.bottomCenter,
child: _buildCartSummary(context),
),
)
],
),
);
}
_buildCartItems() {
return Container(
color: Colors.white,
margin: EdgeInsets.symmetric(vertical: 6.0),
child: Row(
children: <Widget>[
Container(
width: 80.0,
height: 80.0,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(20.0),
),
child: Center(
child: Container(
padding: EdgeInsets.all(4.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
'https://s2.r29static.com/bin/entry/ebd/0,675,2000,1050/x,80/1929471/image.jpg'),
),
),
),
),
),
SizedBox(width: 12.0),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: 100.0,
child: Text(
'Nike Air max',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
SizedBox(height: 8.0),
Row(
children: <Widget>[
Container(
width: 20.0,
height: 20.0,
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadiusDirectional.circular(4.0),
),
child: Icon(
Icons.remove,
color: Colors.white,
size: 15.0,
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Text(
'1',
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 15.0),
),
),
Container(
width: 20.0,
height: 20.0,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadiusDirectional.circular(4.0),
),
child: Icon(
Icons.add,
color: Colors.white,
size: 15.0,
),
),
],
),
],
),
Spacer(),
Text(
'\u20b9 6,000',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0),
),
],
),
);
}
_buildCartSummary(BuildContext context) {
return Container(
height: 200,
color: Colors.white,
padding: EdgeInsets.fromLTRB(15.0, 8.0, 15.0, 0.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'Sub Total',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0),
),
Text(
'\u20b9 480',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0),
),
],
),
SizedBox(height: 10.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'Taxes (absorbed by you)',
style: TextStyle(fontSize: 15.0),
),
Text(
'\u20b9 40',
style: TextStyle(fontSize: 15.0),
),
],
),
SizedBox(height: 10.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'Total',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
),
Text(
'\u20b9 520',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0),
),
],
),
MaterialButton(
onPressed: () {
showModalBottomSheet(
context: context,
isScrollControlled: false,
builder: (context) => SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
// child: ShowPaymentOptionsScreen(),
),
),
);
},
height: 40.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
),
minWidth: double.infinity,
child: Text(
'PROCESS PAYMENT',
style: TextStyle(
color: Colors.white,
fontSize: 14.0,
fontWeight: FontWeight.bold,
),
),
color: Colors.red,
),
SizedBox(height: 15.0),
],
),
);
}
}
Solution 2
Just add Positioned
widget with all dimens as 0.0
Positioned(
bottom: 0.0,
right: 0.0,
left: 0.0,
child: Container(
color: Colors.white,
child: Align(
alignment: Alignment.bottomCenter,
child: _buildCartSummary(context),
),
),
),
Output:
Comments
-
hermie_brown over 1 year
I am building a shopping cart UI and therein I want to display a list of my shopping cart items and also a fixed bottom widget which would show the cart summary details.
I want the cart summary container fixed to the bottom and the ListView.builder scrollable but to sit right ontop of the bottom widget, not disappear in it.
Here's my code. I know it must be something I am overlooking. I need help with that.
Thanks.
class CheckoutScreen extends StatelessWidget { static const String id = 'checkout_screen'; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( leading: IconButton( icon: Icon( Icons.arrow_back_ios, color: Colors.black26, ), onPressed: () => Navigator.pop(context), ), title: Text( 'Shopping cart', style: TextStyle( fontSize: 21.0, color: Colors.black26, fontWeight: FontWeight.bold, ), ), elevation: 0.0, backgroundColor: Colors.white, ), // bottomNavigationBar: _buildCartSummary(context), body: Stack( children: <Widget>[ Container( padding: const EdgeInsets.symmetric(horizontal: 16.0), child: ListView.builder( itemCount: 5, itemBuilder: (context, index) { return _buildCartItems(); }, ), ), SizedBox(height: 30), Container( child: Align( alignment: Alignment.bottomCenter, child: _buildCartSummary(context), ), ), ], ), // Align( // alignment: Alignment.center, // child: Text('Your cart is empty.')), ); } _buildCartItems() { return Container( color: Colors.white, margin: EdgeInsets.symmetric(vertical: 6.0), child: Row( children: <Widget>[ Expanded( child: Container( width: 80.0, height: 80.0, decoration: BoxDecoration( color: Colors.grey[300], borderRadius: BorderRadius.circular(20.0), ), child: Center( child: Container( padding: EdgeInsets.all(4.0), decoration: BoxDecoration( borderRadius: BorderRadius.circular(20.0), image: DecorationImage( fit: BoxFit.cover, image: NetworkImage( 'https://s2.r29static.com/bin/entry/ebd/0,675,2000,1050/x,80/1929471/image.jpg'), ), ), ), ), ), ), SizedBox(width: 12.0), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Container( width: 100.0, child: Text( 'Nike Air max', style: TextStyle(fontWeight: FontWeight.bold), ), ), SizedBox(height: 8.0), Row( children: <Widget>[ Container( width: 20.0, height: 20.0, decoration: BoxDecoration( color: Colors.grey[200], borderRadius: BorderRadiusDirectional.circular(4.0), ), child: Icon( Icons.remove, color: Colors.white, size: 15.0, ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 15.0), child: Text( '1', style: TextStyle( fontWeight: FontWeight.bold, fontSize: 15.0), ), ), Container( width: 20.0, height: 20.0, decoration: BoxDecoration( color: kThemeStyleButtonFillColour, borderRadius: BorderRadiusDirectional.circular(4.0), ), child: Icon( Icons.add, color: Colors.white, size: 15.0, ), ), ], ), ], ), ), Spacer(), Expanded( child: Text( '\u20b9 6,000', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0), ), ), ], ), ); } _buildCartSummary(BuildContext context) { return Container( padding: EdgeInsets.fromLTRB(15.0, 8.0, 15.0, 0.0), child: Column( mainAxisAlignment: MainAxisAlignment.end, children: <Widget>[ Divider(), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ Text( 'Sub Total', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0), ), Text( '\u20b9 480', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0), ), ], ), SizedBox(height: 10.0), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ Text( 'Taxes (absorbed by you)', style: TextStyle(fontSize: 15.0), ), Text( '\u20b9 40', style: TextStyle(fontSize: 15.0), ), ], ), SizedBox(height: 10.0), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ Text( 'Total', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0), ), Text( '\u20b9 520', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0), ), ], ), MaterialButton( onPressed: () { showModalBottomSheet( context: context, isScrollControlled: true, builder: (context) => SingleChildScrollView( child: Container( padding: EdgeInsets.only( bottom: MediaQuery.of(context).viewInsets.bottom), child: ShowPaymentOptionsScreen(), ), ), ); }, height: 40.0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5.0), ), minWidth: double.infinity, child: Text( 'PROCESS PAYMENT', style: TextStyle( color: Colors.white, fontSize: 14.0, fontWeight: FontWeight.bold, ), ), color: kThemeStyleButtonFillColour, ), SizedBox(height: 15.0), ], ), ); } }
-
hermie_brown over 3 yearsBut I noticed with your implementation, the last items on the list disappears in the list view scroll. Try changing the itemCount to something like 7 or 10 to see what I mean.
-
hermie_brown over 3 yearsThanks! This is the best implementation thus far. I'll just add that to avoid the scribbly overflow yellow lines in smaller devices such as Nexus 5, I had to do a small improvement in the Build function. I also wrapped the first Container in the column with an Expanded widget and set the flex to 2. But overall, great fix!