我试图为我的扑动应用程序构建一个简单的登录页面。我已经成功构建了TextFields和登录/登录按钮。我想添加一个水平的ListView。运行代码时,元素消失了,如果没有ListView,也没问题。我怎样才能正确地做到这一点呢?
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text("Login / Signup"),
),
body: new Container(
child: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new TextField(
decoration: new InputDecoration(
hintText: "E M A I L A D D R E S S"
),
),
new Padding(padding: new EdgeInsets.all(15.00)),
new TextField(obscureText: true,
decoration: new InputDecoration(
hintText: "P A S S W O R D"
),
),
new Padding(padding: new EdgeInsets.all(15.00)),
new TextField(decoration: new InputDecoration(
hintText: "U S E R N A M E"
),),
new RaisedButton(onPressed: null,
child: new Text("SIGNUP"),),
new Padding(padding: new EdgeInsets.all(15.00)),
new RaisedButton(onPressed: null,
child: new Text("LOGIN"),),
new Padding(padding: new EdgeInsets.all(15.00)),
new ListView(scrollDirection: Axis.horizontal,
children: <Widget>[
new RaisedButton(onPressed: null,
child: new Text("Facebook"),),
new Padding(padding: new EdgeInsets.all(5.00)),
new RaisedButton(onPressed: null,
child: new Text("Google"),)
],)
],
),
),
margin: new EdgeInsets.all(15.00),
),
),
);
错误原因:
列在主轴方向(纵轴)扩展到最大,ListView也是如此。
解决方案:
你需要限制ListView的高度。有很多方法可以做到这一点,你可以选择最适合你的需要。
如果你想让ListView占用Column内的所有剩余空间,请使用Expanded。
列(
孩子们:<部件> (
Expanded(// <——使用Expanded
孩子:列表视图(…),
)
),
)
如果你想限制你的ListView到一定的高度,使用sizebox。
列(
孩子们:<部件> (
SizedBox (
height: 200, //约束高度。
孩子:列表视图(…),
)
),
)
如果你的ListView很小,你可以尝试使用shrinkWrap属性。
列(
孩子们:<部件> (
列表视图(
shrinkWrap: true, //设置
)
),
)
如果你想让ListView尽可能小,使用Flexible with ListView. shrinkwrap:
列(
孩子们:<部件> (
Flexible(// <——使用Flexible
孩子:列表视图(
shrinkWrap: true, //设置这个
),
)
),
)
正如上面其他人所提到的,带扩展的Wrap listview是解决方案。
但是当你处理嵌套列时,你还需要将你的ListView限制在一定的高度(面对这个问题很多)。
如果有人有其他的解决方案,请在评论中提及或补充答案。
例子
SingleChildScrollView(
child: Column(
children: <Widget>[
Image(image: ),//<< any widgets added
SizedBox(),
Column(
children: <Widget>[
Text('header'), //<< any widgets added
Expanded(child:
ListView.builder(
//here your code
scrollDirection: Axis.horizontal,
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
return Container();
}
)
),
Divider(),//<< any widgets added
],
),
],
),
);
尝试使用Slivers:
Container(
child: CustomScrollView(
slivers: <Widget>[
SliverList(
delegate: SliverChildListDelegate(
[
HeaderWidget("Header 1"),
HeaderWidget("Header 2"),
HeaderWidget("Header 3"),
HeaderWidget("Header 4"),
],
),
),
SliverList(
delegate: SliverChildListDelegate(
[
BodyWidget(Colors.blue),
BodyWidget(Colors.red),
BodyWidget(Colors.green),
BodyWidget(Colors.orange),
BodyWidget(Colors.blue),
BodyWidget(Colors.red),
],
),
),
SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
delegate: SliverChildListDelegate(
[
BodyWidget(Colors.blue),
BodyWidget(Colors.green),
BodyWidget(Colors.yellow),
BodyWidget(Colors.orange),
BodyWidget(Colors.blue),
BodyWidget(Colors.red),
],
),
),
],
),
),
)
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text("Login / Signup"),
),
body: new Container(
child: new Center(
child: ListView(
//mainAxisAlignment: MainAxisAlignment.center,
scrollDirection: Axis.vertical,
children: <Widget>[
new TextField(
decoration: new InputDecoration(
hintText: "E M A I L A D D R E S S"
),
),
new Padding(padding: new EdgeInsets.all(15.00)),
new TextField(obscureText: true,
decoration: new InputDecoration(
hintText: "P A S S W O R D"
),
),
new Padding(padding: new EdgeInsets.all(15.00)),
new TextField(decoration: new InputDecoration(
hintText: "U S E R N A M E"
),),
new RaisedButton(onPressed: null,
child: new Text("SIGNUP"),),
new Padding(padding: new EdgeInsets.all(15.00)),
new RaisedButton(onPressed: null,
child: new Text("LOGIN"),),
new Padding(padding: new EdgeInsets.all(15.00)),
new ListView(scrollDirection: Axis.horizontal,
children: <Widget>[
new RaisedButton(onPressed: null,
child: new Text("Facebook"),),
new Padding(padding: new EdgeInsets.all(5.00)),
new RaisedButton(onPressed: null,
child: new Text("Google"),)
],)
],
),
),
margin: new EdgeInsets.all(15.00),
),
),
);
Column(
children: <Widget>[
Text('Leading text widget'),
ListView(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
children: <Widget>[
ListTile(
leading: Icon(Icons.map),
title: Text('Map'),
),
ListTile(
leading: Icon(Icons.photo_album),
title: Text('Album'),
),
ListTile(
leading: Icon(Icons.phone),
title: Text('Phone'),
),
],
),
Text('More widget'),
],
);
只使用
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
listView中的属性
另外,您可以尝试使用CustomScrollView
CustomScrollView(
controller: _scrollController,
slivers: <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
final OrderModel order = _orders[index];
return Container(
margin: const EdgeInsets.symmetric(
vertical: 8,
),
child: _buildOrderCard(order, size, context),
);
},
childCount: _orders.length,
),
),
SliverToBoxAdapter(
child: _buildPreloader(context),
),
],
);
提示:_buildPreloader返回CircularProgressIndicator或Text
在我的情况下,我想在ListView下显示一些小部件。我不喜欢使用列,因为列中的ListView周围的小部件总是在屏幕上显示“向上”,比如“绝对位置”
对不起,我的英语不好
[解决方案预览]-[列表项可滚动,但标题固定]
我有一个非常小而直接的答案,看到将listview放在列内将迫使列无限扩展,这基本上是一个错误的事情。
现在如果你把物理:NeverScrollableScrollPhysics(),就像其他人建议的那样,在listview中,那么如果你禁用了listview内部的滚动,有什么意义呢?
有一个简单的解决办法,坦率地说,我通过撞击和试验来解决这个问题。代码后让我给大家做个小解释。
Column(
children: [
Text(
"All Bookings",
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600, color: Colors.brown[700]),
),
Expanded(
child: Container(
margin: EdgeInsets.only(top: 24),
child: ListView.builder(
itemCount: 30,
itemBuilder: (BuildContext context, int index) => ListTile(
title: Text("List Item ${index + 1}"),
),
),
),
),
],
)
我有要求有标题内列作为第一个元素,然后放一个列表视图,以便用户可以有滚动列表。这是一种通用的需求。你也可以把这个放在底页或模态中。
代码的解释:
我把第一个子作为标题在列内ok(我不想滚动,我想它是固定的)
我在列内扩展了子列,这就像获得列中所有的“剩余空间”。
在我保留的容器(只是在标题和列表视图之间放一些空间)这是可选的,你可以删除容器,它仍然会工作。
Listview的约束很好它不会在列中无限拉伸。作为扩展小部件已经约束它。
请纠正我,如果我错了,或者如果这段代码不工作(它工作到现在没有错误:)