![](/img/trans.png)
[英]How to implement a SingleChildScrollView(with horizontal listview and vertical gridview) inside a TabBarView
[英]Vertical ListView inside horizontal SingleChildScrollView
我需要构建一个页面,其中包含分组在一行中的对象列表。 这需要垂直滚动(以显示更多组)和水平滚动(以显示子组)。 垂直和水平滚动需要完全移动项目。 像这样的东西: https://gph.is/g/46gjW0q
我正在使用以下代码执行此操作:
Widget _buildGroups() {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Container(
width: 2000,
child: ListView.builder(
scrollDirection: Axis.vertical,
itemCount: boardData.length,
itemBuilder: (context, index) {
return Row(children: _buildSingleGroup(index));
},
),
),
);
}
List<Widget> _buildSingleGroup(int groupIndex) {
return List.generate(...);
}
我需要它是水平动态的,但在这里,如您所见,我需要设置一个宽度,否则会发生错误:
══════════════════ Exception caught by rendering library ═════════════════════
The following assertion was thrown during performResize()
Vertical viewport was given unbounded width.
Viewports expand in the cross axis to fill their container and constrain their
children to match their extent in the cross axis. In this case, a vertical
viewport was given an unlimited amount of horizontal space in which to expand.
我试图在 ListView 中设置“shrinkWrap:true”,但结果给出了另一个错误:
Failed assertion: line 1629 pos 16: 'constraints.hasBoundedWidth': is not true.
那么如何使用动态 ListView 宽度来做到这一点呢?
发生错误是因为当ListView
尝试从其父级获取高度以填充整个高度时,父级返回无穷大高度,因为SingleChildScrollView
没有固定的容器高度值。 要解决该问题,您需要限制高度值。 例如,我使用SizedBox
为ListView
指定高度。
以下代码适用于我。
SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(
height: 120, // <-- you should put some value here
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: items.length,
itemBuilder: (context, index) {
return Text('it works');
},
),
),
],
),
);
请你能解释一下你对物体大小的猜测吗?
我有一个解决方案,但在我的解决方案中,flutter 将为第一帧构建所有对象(在两个轴上)。 并再次构建三个中的任何 setState。 所以它不是很好的解决方案。
///
class BothAxisScroll extends StatefulWidget {
@override
_BothAxisScrollState createState() => _BothAxisScrollState();
}
class _BothAxisScrollState extends State<BothAxisScroll> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.all(30),
child: Container(
alignment: Alignment.topLeft,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: _build(),
),
),
),
),
),
);
}
}
List<Widget> _build() {
return List.generate(
20,
(index) => Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: _buildSingleGroup(index),
));
}
List<Widget> _buildSingleGroup(int _index) {
return List.generate(
Random().nextInt(20),
(index) {
print('BUILD: $_index');
return Container(
padding: const EdgeInsets.all(15), child: Text("$_index-$index"));
},
);
}
并产生第一帧:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.