在 Column Flutter 中居中展开 ListView
Posted
技术标签:
【中文标题】在 Column Flutter 中居中展开 ListView【英文标题】:Center Expanded ListView inside Column Flutter 【发布时间】:2019-05-03 19:22:46 【问题描述】:我正在尝试构建一个布局,其中顶部和底部有两个 Text 对象,它们保持静止,一个 ListView 在它们的中心。
这是屏幕的代码
class HomeScreen extends StatelessWidget
@override
Widget build(BuildContext context)
return Scaffold(
body: SafeArea(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 40.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(vertical: 40.0),
child: Text(
DateFormat("hh:mm 'PM ,' MMMM d").format(DateTime.now()),
style: Theme.of(context).textTheme.title,
),
),
Expanded(
child: ListView.builder(
itemCount: 4,
itemBuilder: (BuildContext context, int index) =>
CustomAppText(
text: 'Custom App',
),
),
),
Container(
margin: EdgeInsets.symmetric(vertical: 40.0),
child: Text(
"Settings",
style: Theme.of(context).textTheme.title,
),
),
],
),
),
),
);
给定代码的输出
我正在寻找的设计
我尝试过使用 Center 小部件,但它没有使 ListView 居中
【问题讨论】:
【参考方案1】:ListView 填充了整个 Expanded Widget,这就是为什么使用 Center 小部件不起作用的原因,所以应该添加 shrinkWrap: true
,这样 ListView 只需要它的孩子的高度。
在浏览了我找到的关于灵活小部件的文档后
Flexible, which does not force the child to fill the available space.
做出改变并像魅力一样工作
Flexible(
child: ListView.builder(
shrinkWrap: true,
itemCount: 4,
itemBuilder: (BuildContext context, int index) =>
CustomAppText(
text: 'Custom App',
),
),
),
【讨论】:
这实际上并不能解决问题。现在 ListView 没有展开,它只占用了足够的空间。 完美答案:) 完美答案...【参考方案2】:对于那些仍在寻找答案的人,这对我有用:
Column(
children: [
Container(), // some top content
Expanded(
child: Center(
child: ListView(
shrinkWrap: true,
children: [] //your list view content here
)
)
),
Container(), // some bottom content
]
)
扩展小部件使内容占据所有可用空间。
Center 小部件将您要显示的内容居中。
ListView 保存您的列表内容,"shrinkWrap: true" 属性使您的列表视图根据内容大小缩小(允许它由 在不占用大量空间时居中小部件)。
【讨论】:
感谢您的解决方案和解释。【参考方案3】:希望对您有所帮助。为顶部和底部小部件提供 25% 的屏幕尺寸。为列表视图设置屏幕大小的 50%。
import 'package:flutter/material.dart';
class TestPage extends StatefulWidget
@override
_TestPageState createState() => _TestPageState();
class _TestPageState extends State<TestPage>
@override
Widget build(BuildContext context)
final _size = MediaQuery.of(context).size;
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(28.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// Top Widgets
Container(
width: double.infinity,
// color: Colors.green,
height: _size.height * 0.25, // Take 25% width of the screen height
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('11: 25 AM', style: TextStyle(fontSize: 23.0),),
Text('Set As Launcher', style: TextStyle(fontSize: 23.0),)
],
),
),
Expanded(
child: Container(
// color: Colors.yellow,
child: ListView(
children: List.generate(25, (index)
return Text('Custom App $index', style: TextStyle(fontSize: 45.0),);
),
),
),
),
// Bottom Widgets
Container(
width: double.infinity,
// color: Colors.blue,
height: _size.height * 0.25, // Take 25% width of the screen height
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Settings', style: TextStyle(fontSize: 23.0),),
],
),
)
],
),
),
),
);
【讨论】:
【参考方案4】:只需在Column
中添加一个Expanded
作为您的第一个Container
的包装器
Expanded(
child: Container(
margin: EdgeInsets.symmetric(vertical: 40.0),
child: Text(
DateFormat("hh:mm 'PM ,' MMMM d").format(DateTime.now()),
style: Theme.of(context).textTheme.title,
),
),
),
【讨论】:
这会将整个列向下推到设置附近,而不是中心【参考方案5】:只需将您的 ListView.builder 包装在一个容器类中并给它一个高度,明确地以双倍或屏幕高度的百分比表示。
class Trial extends StatelessWidget
@override
Widget build(BuildContext context)
return Scaffold(
body: SafeArea(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 40.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(vertical: 40.0),
child: Text(
"Some Text",
style: Theme.of(context).textTheme.title,
),
),
Container(
// height: 40,
height: MediaQuery.of(context).size.height * 0.4,
child: ListView.builder(
itemCount: 20,
itemBuilder: (BuildContext context, int index)
return Text("Hello");
),
),
Container(
margin: EdgeInsets.symmetric(vertical: 40.0),
child: Text(
"Settings",
style: Theme.of(context).textTheme.title,
),
),
],
),
),
),
);
【讨论】:
【参考方案6】:添加两个垫片,它会给您 100% 与您预期相同的结果
Spacer(),
Expanded(
child: ListView.builder(
itemCount: 4,
itemBuilder: (BuildContext context, int index) =>
CustomAppText(
text: 'Custom App',
),
),
),
Spacer(),
【讨论】:
【参考方案7】:如果你用Container
替换你的Expanded
小部件并给它一个固定的height
,我想你会得到你想要的。
【讨论】:
这意味着我必须明确提供一个高度,这是一个 hacky 解决方案 您需要将 CustomAppText 中的小部件居中,这看起来好像列表视图位于中心。以上是关于在 Column Flutter 中居中展开 ListView的主要内容,如果未能解决你的问题,请参考以下文章