Flutter:我的 Listview.builder 消失在我的固定底部容器下
Posted
技术标签:
【中文标题】Flutter:我的 Listview.builder 消失在我的固定底部容器下【英文标题】:Flutter: My Listview.builder disappears under my Fixed bottom Container 【发布时间】:2021-01-05 07:46:06 【问题描述】:我正在构建一个购物车 UI,我想在其中显示我的购物车商品列表以及一个固定的底部小部件,该小部件将显示购物车摘要详细信息。
我希望购物车摘要容器固定在底部,并且 ListView.builder 可滚动,但要位于底部小部件的正上方,而不是消失在其中。
这是我的代码。我知道这一定是我忽略的东西。我需要这方面的帮助。
谢谢。
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),
],
),
);
【问题讨论】:
【参考方案1】:请在此处查看已编辑的代码。
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),
],
),
);
【讨论】:
谢谢!这是迄今为止最好的实现。我只是补充一点,为了避免在 Nexus 5 等小型设备中出现潦草溢出的黄线,我必须对 Build 功能进行小幅改进。我还使用 Expanded 小部件将列中的第一个 Container 包装起来,并将 flex 设置为 2。但总的来说,很好的修复!【参考方案2】:只需添加所有尺寸为 0.0 的 Positioned
小部件
Positioned(
bottom: 0.0,
right: 0.0,
left: 0.0,
child: Container(
color: Colors.white,
child: Align(
alignment: Alignment.bottomCenter,
child: _buildCartSummary(context),
),
),
),
输出:
【讨论】:
但我注意到在您的实现中,列表中的最后一项在列表视图滚动中消失了。尝试将 itemCount 更改为 7 或 10 以了解我的意思。【参考方案3】:尝试向 ListView 添加填充并将固定高度设置为底部容器。内边距和底部容器高度应该相同
body: Stack(
children: <Widget>[
Container(
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 30),
child: ListView.builder(
itemCount: 5,
itemBuilder: (context, index)
return _buildCartItems();
,
),
),
Container(
height: 30,
child: Align(
alignment: Alignment.bottomCenter,
child: _buildCartSummary(context),
),
),
],
),
【讨论】:
以上是关于Flutter:我的 Listview.builder 消失在我的固定底部容器下的主要内容,如果未能解决你的问题,请参考以下文章
我在运行我的应用程序(Flutter、FireBase)时收到此 E/flutter (25055) 错误
为啥我的 Flutter 应用的列表视图滚动不如 Flutter Gallery 应用流畅?