垂直视口被赋予无限高度

时间:2018-05-09 11:43:40

标签: flutter flutter-layout

我是新来的人。只需将我的网格视图居中:

enter image description here

以下是我尝试过的代码:

  @override
  Widget build(BuildContext context) {
    return new Material(
      color: Colors.deepPurpleAccent,
      child: new Column(
       mainAxisAlignment: MainAxisAlignment.center,
          children:<Widget>[new GridView.count(crossAxisCount: _column,children: new List.generate(_row*_column, (index) {
            return new Center(
                child: new CellWidget()
            );
          }),)]
      )
    );
  }

例外情况如下:

    I/flutter ( 9925): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 9925): The following assertion was thrown during performResize():
I/flutter ( 9925): Vertical viewport was given unbounded height.
I/flutter ( 9925): Viewports expand in the scrolling direction to fill their container.In this case, a vertical
I/flutter ( 9925): viewport was given an unlimited amount of vertical space in which to expand. This situation
I/flutter ( 9925): typically happens when a scrollable widget is nested inside another scrollable widget.
I/flutter ( 9925): If this widget is always nested in a scrollable widget there is no need to use a viewport because
I/flutter ( 9925): there will always be enough vertical space for the children. In this case, consider using a Column
I/flutter ( 9925): instead. Otherwise, consider using the "shrinkWrap" property (or a ShrinkWrappingViewport) to size
I/flutter ( 9925): the height of the viewport to the sum of the heights of its children.
I/flutter ( 9925): 
I/flutter ( 9925): When the exception was thrown, this was the stack:
I/flutter ( 9925): #0      RenderViewport.performResize.<anonymous closure> (package:flutter/src/rendering/viewport.dart:827:15)
I/flutter ( 9925): #1      RenderViewport.performResize (package:flutter/src/rendering/viewport.dart:880:6)
I/flutter ( 9925): #2      RenderObject.layout (package:flutter/src/rendering/object.dart:1555:9)

提前致谢!

16 个答案:

答案 0 :(得分:39)

当您尝试在ListView内使用GridView / Column时,通常会发生这种情况,有很多解决方法,在此我列举的很少。

  1. ListView中包装Expanded

    Column(
      children: <Widget>[
        Expanded( // wrap in Expanded
          child: ListView(...),
        ),
      ],
    )
    
  2. ListView包裹在SizedBox中,并给出有界的height

    Column(
      children: <Widget>[
        SizedBox(
          height: 400, // fixed height
          child: ListView(...),
        ),
      ],
    )
    
  3. shrinkWrap: true中使用ListView

    Column(
      children: <Widget>[
        ListView(
          shrinkWrap: true, // use this
        ),
      ],
    )
    

答案 1 :(得分:15)

添加这两行

ListView.builder(
    scrollDirection: Axis.vertical,
    shrinkWrap: true,
...

答案 2 :(得分:13)

在灵活或扩展的小部件中放入网格视图

return new Material(
    color: Colors.deepPurpleAccent,
    child: new Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children:<Widget>[
         Flexible(
          child:  GridView.count(crossAxisCount: _column,children: new List.generate(_row*_column, (index) {
          return new Center(
             child: new CellWidget(),
          );
        }),))]
    )
);

答案 3 :(得分:13)

这种情况通常发生在将可滚动小部件嵌套在另一个可滚动小部件内时。

在我的情况下,我在Column内使用GridView并抛出该错误。

GridView小部件具有shrinkWrap属性/命名参数,可以true对其进行设置,我的问题已解决。

GridView.count(
  shrinkWrap: true,
  // rest of code
)

答案 4 :(得分:8)

因此,每个人都发布了答案,但没人愿意解释原因: 我将复制有关shrinkWrap的文档:

  

[scrollDirection]中滚动视图的范围是否应为   由所查看的内容确定。

     

如果滚动视图不收缩包装,则滚动视图将展开   到[scrollDirection]中允许的最大大小。如果滚动视图   在[scrollDirection]中具有无限制的约束,则[shrinkWrap]必须   是真的。

     

收缩包装滚动视图的内容要多得多   比扩展到最大允许大小要昂贵,因为内容   可以在滚动过程中扩展和收缩,这意味着   每当滚动位置更改时,都需要重新计算滚动视图。

     

默认为false

因此,按照文档的词汇表,这里发生的是,我们的ListView处于无限制约束 的情况下(按照我们的方向正在滚动),因此ListView会抱怨:

  

...在一个垂直视口中,   进行扩展。

只需将shrinkWrap设置为true,即可确保它包装了内容定义的大小。示例代码说明:

// ...
  ListView(
    // Says to the `ListView` that it must wrap its
    // height (if it's vertical) and width (if it's horizontal).
    shrinkWrap: true,
  ),
// ...

这就是您的代码所要解决的问题,不过,@Rémi建议最适合这种情况,使用Align而不是Column

答案 5 :(得分:5)

尽管shrinkWrap可以执行此操作,但是您无法滚动ListView

如果要滚动功能,可以添加physics属性:

ListView.builder(
    scrollDirection: Axis.vertical,
    shrinkWrap: true,
    physics: ScrollPhysics(),
...

答案 6 :(得分:3)

请勿使用Column进行单个子对齐。请改用Align

    new Align(
      alignment: Alignment.topCenter,
      child: new GridView(),
    )

答案 7 :(得分:3)

此答案基于@CopsOnRoad的北部

之所以发生这种情况,是因为ListView/GridView小部件没有父级可以接受其大小,因此其高度是无限的,并且颤振不知道ListView的高度并且无法呈现。

  1. 解决方案一:固定高度

    直接用ContainerSizedBox包裹起来以写出静高。

    Column(
      children: <Widget>[
        SizedBox(
         height: 400, // fixed height
        child: ListView(...),
       ),
     ],
    )
    

这很好,但是如果高度需要自适应,那么编写该高度将无效。

  1. 解决方案二:收缩包装:是

    尝试将shrinkWrap: truephysics: ScrollPhysics()进行滚动

    shrinkWrap: true有点像android的wrap_content

    ListView.builder(
       scrollDirection: Axis.vertical,
       shrinkWrap: true,
       physics: ScrollPhysics()
    ...
    

但是,编译后,您会在页面底部看到一个黄色的长警告。

所以仍然不能

  1. 解决方案三:扩展或灵活

    Flexible是一种灵活的布局,等效于android中的LinearLayout。

    Flexible flex中有一个属性,它等于layout_weight,占据了所有剩余空间。

    因此,我们可以使用Flexible包装ListView。

    Column(
      children: <Widget>[
        Expanded( 
          child: ListView(...),
        ),
      ],
    )
    

此答案基于:Vertical viewport was given unbounded height.

答案 8 :(得分:1)

您的专栏不知道需要多少高度。 使用Flexible来包装您的Column,它可以灵活地扩展和填充主轴上的可用空间。

  @override
  Widget build(BuildContext context) {
    return new Material(
        color: Colors.deepPurpleAccent,
        child: Flexible(
            child: new Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children:<Widget>[new GridView.count(crossAxisCount: _column,children: new List.generate(_row*_column, (index) {
                  return new Center(
                      child: new CellWidget()
                  );
                }),)]
            )
        )
    );
  }

答案 9 :(得分:1)

对此列表进行第二次测试

ListView.builder(
            physics: NeverScrollableScrollPhysics(),

答案 10 :(得分:1)

    Container(
       height: 100,
       child: ListView.builder(
       scrollDirection: Axis.vertical,
       physics: BouncingScrollPhysics(),
       shrinkWrap: true,
       itemCount: 5,
       itemBuilder: (context, index) {
       return Text("Hello World $index");
      },
    ),
  );

答案 11 :(得分:1)

我想发布另一个答案,因为许多答案(包括已接受的答案!)都建议在 shrinkWrap: true 中使用 ListView.builder。虽然这消除了错误,但对于这种情况,此解决方案是 NOT ideal for performance reasons。 Flutter 将 ListView 设计为无限大小,专门用于仅在必要时阻止这种行为!

<块引用>

收缩包裹滚动视图的内容比扩展到允许的最大大小要昂贵得多,因为内容在滚动过程中可以扩展和收缩,这意味着滚动视图的大小需要在滚动位置发生变化时重新计算。

在某些情况/设备中,此属性会导致我的项目出现故障滚动和动画延迟。即使延迟不明显,此属性也会影响滚动性能。

OP 显示他正在为 ListView 创建小(有限)数量的孩子。如果我们想解决这些列表的错误,Google recommends 可以使用 Flexible 小部件,即列表本身的 Expanded(带有 flex 1 的 Flexible)。

Expanded(
    child: ListView(
        ...
    ),
) 

这里还有其他布局问题,但垂直视口无界高度是因为 ListView 没有限制其大小的父级。

答案 12 :(得分:0)

如果您在 2021 年仍然面临这个问题..这是最好且简单的解决方案

      ListView.builder(
         scrollDirection: Axis.vertical,
         shrinkWrap: true,
     //     itemExtent: 400, use this if you give hight of your items
        physics: ScrollPhysics(),)
<块引用>

他们有很多解决方案..但是他们有问题..就像当我们使用 ListView 并使用它的属性 shrinkWrap .然后你会注意到滚动在 listView 上不起作用的一件事所以你必须使用物理:ScrollPhysics()

答案 13 :(得分:0)

解决上述问题的两种方法

1.使用灵活的小部件,

Flexible 小部件可以在 Row、Column 和 Flex 内使用。灵活扩展以填充主轴上的可用空间(例如,水平用于 [Row] 或垂直用于 [Column] )

但是,请记住,与 Expanded 不同的是,Flexible 小部件不需要孩子填充可用空间。因此,最好使用 Flexible

Column(
  children: <Widget>[
    Flexible( 
      child: ListView(...),
    ),
  ],
)

2.使用shrinkWrap:true

使用 shrinkWrap 为真,我们告诉 Listview 将其 List 呈现到可用空间,而不是在剩余屏幕下方。

Column(
  children: <Widget>[
    ListView(
      shrinkWrap: true, 
    ),
  ],
)

此外,physics 属性可用于允许/禁止滚动 Listview

停止滚动

 ListView(
      shrinkWrap: true, 
      physics: NeverScrollableScrollPhysics(),
    ),

允许滚动

 ListView(
      shrinkWrap: true, 
      physics: ScrollPhysics(),
    ),

 

答案 14 :(得分:-1)

有一个名为Center的小部件。它应该可以帮助您实现想要做的事情(垂直居中)。 Official Documentation for Center widget

答案 15 :(得分:-1)

答案有很多,但每个都有自己的局限性。每个人都说使用 shrinkWrap: true。是的,你应该使用它,但这些代码的效果是当你滚动列表时,它会自动移动到顶部项目,意味着滚动回顶部。 所以完美的解决方案是使用带有物理的shrinkwrap,然后只有列表才能平滑滚动。

      shrinkWrap: true,          //
      physics: ScrollPhysics(),  // both line is mandatory

如果您想查看以列为子项且列表可以垂直滚动的 Listview.builder 的其他示例,那么您可以see the example here - 在垂直列表中排列多个文本。