在Flutter中 如果使用 listview 嵌套 listview(gridView) 的方式(其实不是很推荐这么写)直接写 会发现布局不显示。 搜索一下基本上解决方法都是给内部的 listview 设置一个高度,但是针对高度不固定的listview这种方式基本无效,而且设置固定高度后 listview 的性能会有额外开销(因为不可见的item不能被回收了)
解决方法
其实查找一下源码,就可以发现官方已经给出了解决方法,在注释里:
/// Here are two brief snippets showing a [ListView] and its equivalent using
/// [CustomScrollView]:
///
/// ```dart
/// ListView(
/// shrinkWrap: true,
/// padding: const EdgeInsets.all(20.0),
/// children: <Widget>[
/// const Text('I\'m dedicating every day to you'),
/// const Text('Domestic life was never quite my style'),
/// const Text('When you smile, you knock me out, I fall apart'),
/// const Text('And I thought I was so smart'),
/// ],
/// )
/// ```
所以比较简单了,直接在子listview中加上shrinkWrap: true
属性:
ListView childListView = ListView.builder(
itemCount: 10,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
return Container(
color: Colors.primaries[index % Colors.primaries.length],
child: SizedBox(
width: 100.0,
/// 利用index创建伪随机高度的条目
height: 50.0 + ((27 * index) % 15) * 3.14,
child: Center(
child: Text('$index'),
),
),
);
},
);
OK,运行一下发现已经可以显示出正常布局了,是不是很高兴呢。@(滑稽),然而。。。滚动一下发现不能滚动。@(汗)原因是因为 子listview自带滚动属性,使得页面无法随着父控件滚动,所以我们需要禁用 listview的滚动属性。
使用: physics: NeverScrollableScrollPhysics(),
即可禁用listview的滚动,(physics属性在所有滚动空间中均有,系统提供了两个子类,AlwaysScrollableScrollPhysics
,NeverScrollableScrollPhysics
有兴趣可以了解一下ScrollPhysics)
至此,我们运行一下,发现布局正确显示,滑动也没什问题了!
完整代码:
···
ListView childListView = ListView.builder(
itemCount: 10,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
return Container(
color: Colors.primaries[index % Colors.primaries.length],
child: SizedBox(
width: 100.0,
height: 50.0 + ((27 * index) % 15) * 3.14,
child: Center(
child: Text('$index'),
),
),
);
},
);
var listView = ListView.builder(
itemCount: 5,
itemBuilder: (BuildContext context, int index) {
return childListView;
},
);
···