Flutter 垂直ListView在水平SingleChildScrollView中

Flutter 垂直ListView在水平SingleChildScrollView中,flutter,flutter-layout,Flutter,Flutter Layout,我需要构建一个页面,其中包含一行中分组的对象列表。这需要垂直滚动(显示更多组)和水平滚动(显示组子项)。 垂直和水平滚动需要同时移动项目。 大概是这样的: 我使用以下代码执行此操作: Widget\u buildGroups(){ 返回SingleChildScrollView( 滚动方向:轴水平, 子:容器( 宽度:2000, 子项:ListView.builder( 滚动方向:轴垂直, itemCount:boardData.length, itemBuilder:(上下文,索引){ 返回行

我需要构建一个页面,其中包含一行中分组的对象列表。这需要垂直滚动(显示更多组)和水平滚动(显示组子项)。 垂直和水平滚动需要同时移动项目。 大概是这样的:

我使用以下代码执行此操作:

Widget\u buildGroups(){
返回SingleChildScrollView(
滚动方向:轴水平,
子:容器(
宽度:2000,
子项:ListView.builder(
滚动方向:轴垂直,
itemCount:boardData.length,
itemBuilder:(上下文,索引){
返回行(子项:_buildSingleGroup(索引));
},
),
),
);
}
列表_buildSingleGroup(int groupIndex){
返回列表。生成(…);
}
我需要这是水平动态的,但正如您所看到的,我需要设置宽度,否则会发生错误:

══════════════════ 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
没有固定的容器高度值。要解决此问题,需要限制高度值。例如,我曾经为
ListView
指定高度

下面的代码适合我

SingleChildScrollView(
子:列(
mainAxisSize:mainAxisSize.min,
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
大小盒子(

身高:120,//请解释一下你对物体大小的猜测

我有一个解决方案,但在我的解决方案中,颤振将为第一帧构建所有对象(在两个轴上)。并再次构建三个帧中的任何设置状态。因此,这不是好的孤立

最后一次滚动水平偏移 和 但我还是会解释的

///
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"));
    },
  );
}
///
类BothAxisScroll扩展StatefulWidget{
@凌驾
_BothAxisScrollState createState()=>BothAxisScrollState();
}
类_bothaxiscrollstate扩展状态{
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:SingleChildScrollView(
滚动方向:轴水平,
填充:常量边集。全部(30),
子:容器(
对齐:alignment.topLeft,
孩子:填充(
填充:常数边集全部(8.0),
子:SingleChildScrollView(
子:列(
mainAxisAlignment:mainAxisAlignment.start,
crossAxisAlignment:crossAxisAlignment.start,
子项:_build(),
),
),
),
),
),
);
}
}
列表_build(){
返回列表。生成(
20,
(索引)=>行(
crossAxisAlignment:crossAxisAlignment.start,
mainAxisAlignment:mainAxisAlignment.start,
子项:_buildSingleGroup(索引),
));
}
列表buildSingleGroup(int index){
返回列表。生成(
随机().nextInt(20),
(索引){
打印('BUILD:$_index');
返回容器(
padding:const-EdgeInsets.all(15),child:Text(“$索引-$索引”);
},
);
}
并导致第一帧:


你不使用嵌套的ListView有什么原因吗?ListView带有垂直滚动,而在另一个ListView的内部带有水平滚动Hi@Gino,如果我想像你说的那样,每一行都会自己滚动,那不是我想要的行为,我还应该提到,我需要使用ListView小部件,以便实现loadMoreRows函数选择加载更多数据,如果可能的话,不要让flatter重新加载页面中的所有小部件。我已经使用SingleChildScrollView和List实现了想要的结果,但这不允许我以有效的方式处理loadMoreRows