简体   繁体   English

水平 SingleChildScrollView 内的垂直 ListView

[英]Vertical ListView inside horizontal SingleChildScrollView

I need to build a page with lists of objects that are grouped in a single line.我需要构建一个页面,其中包含分组在一行中的对象列表。 This needs to be scrolled both vertically (to show more groups) and horizontally (to show groups children).这需要垂直滚动(以显示更多组)和水平滚动(以显示子组)。 The vertical and horizontal scroll needs to move the items altogether.垂直和水平滚动需要完全移动项目。 Something like this: https://gph.is/g/46gjW0q像这样的东西: https://gph.is/g/46gjW0q

I'm doing this with this code:我正在使用以下代码执行此操作:

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(...);
}

I need this to be horizontally dynamic but here, as you can see, I need to set a width cause otherwise an error occurs:我需要它是水平动态的,但在这里,如您所见,我需要设置一个宽度,否则会发生错误:

══════════════════ 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.

I tried to set "shrinkWrap: true" in the ListView but the result gives another error:我试图在 ListView 中设置“shrinkWrap:true”,但结果给出了另一个错误:

Failed assertion: line 1629 pos 16: 'constraints.hasBoundedWidth': is not true.

So how do you do this with a dynamical ListView width?那么如何使用动态 ListView 宽度来做到这一点呢?

The error happens because when ListView tries to get height from its parent to fill the entire height, the parent returns infinity height because SingleChildScrollView doesn't have fixed container height value.发生错误是因为当ListView尝试从其父级获取高度以填充整个高度时,父级返回无穷大高度,因为SingleChildScrollView没有固定的容器高度值。 To fix that issue you need to limit the height value.要解决该问题,您需要限制高度值。 For example, I used SizedBox to specify height for ListView .例如,我使用SizedBoxListView指定高度。

The following code works for me.以下代码适用于我。

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');
          },
        ),
      ),
    ],
  ),
);

Please can you explain your guess about the objects size?请你能解释一下你对物体大小的猜测吗?

I have a solution, but in my solution, flutter will build all objects (In both axes) for first frame.我有一个解决方案,但在我的解决方案中,flutter 将为第一帧构建所有对象(在两个轴上)。 And build again any setState in the three.并再次构建三个中的任何 setState。 So its not good solition.所以它不是很好的解决方案。

Last scroll offset horizontally最后滚动水平偏移在此处输入图像描述 and在此处输入图像描述 But I'll explain anyway.但无论如何我会解释的。

///
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"));
    },
  );
}

and result in first frame:并产生第一帧:

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在TabBarView中实现SingleChildScrollView(带有水平列表视图和垂直gridview) - How to implement a SingleChildScrollView(with horizontal listview and vertical gridview) inside a TabBarView Flutter SingleChildScrollView(Horizontal) 在另一个 SingleChildScrollView(Vertical) 中 - Flutter SingleChildScrollView(Horizontal) within another SingleChildScrollView(Vertical) Vertical SliverList 内带有水平 ListView 的奇怪错误 - Strange Bug with horizontal ListView inside Vertical SliverList Stack 内部的 ListView 内部的 SingleChildScrollView - ListView inside Stack Inside SingleChildScrollView Flutter 中垂直滚动视图内的水平列表视图 - Horizontal ListView inside a Vertical ScrollView in Flutter 有没有办法在 Flutter 中的另一个 SingleChildScrollView(Horizo​​ntal) 中嵌入 SingleChildScrollView (Vertical) - is there a way to embed a SingleChildScrollView (Vertical) within another SingleChildScrollView(Horizontal) in Flutter 如何在 SingleChildScrollView 中使用 Listview? - How to use Listview inside SingleChildScrollView? 在 SingleChildScrollView 中实现嵌套的 ListView - implementing nested ListView inside SingleChildScrollView 在SingleChildScrollView内是否有ListView是不可能的? - Is it impossible to have ListView inside SingleChildScrollView? 在垂直列表视图中添加水平列表视图时不正确使用 ParentDataWidget - Incorrect use of ParentDataWidget when adding horizontal listview inside vertical listview
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM