【问题标题】:Flutter ListView crashes inside columnFlutter ListView 在列内崩溃
【发布时间】:2019-05-16 18:26:54
【问题描述】:

我需要一些帮助来弄清楚如何呈现 ListView。

我一直在关注 Flutter 教程,但我不得不停下来,因为我无法解决这个问题。

据我所知,ListView 试图占用无限量的空间,这显然会使应用程序崩溃。

我也开始明白,您不能将 ListView 作为 Column/Row 的直接子项(我在下面解释了我尝试做的事情) https://flutter.io/docs/development/ui/layout/box-constraints#flex

代码如下:

@override
Widget build(BuildContext context) {
  return Column(
    children: <Widget>[
      Container(
        margin: EdgeInsets.all(10),
        child: ProductControl(_addProduct),
      ),
      ListView.builder(
        itemCount: _products.length,
        itemBuilder: (BuildContext context, int index) => Card(
              child: Column(
                children: <Widget>[
                  Image.asset('assets/food.jpg'),
                  Text(_products[index])
                ],
              ),
            ),
      )
    ],
  );
}

这就是堆栈跟踪开头所说的内容:

flutter: ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
flutter: The following assertion was thrown during performResize():
flutter: Vertical viewport was given unbounded height.
flutter: Viewports expand in the scrolling direction to fill their 
container.In this case, a vertical
flutter: viewport was given an unlimited amount of vertical space in 
which to expand. This situation
flutter: typically happens when a scrollable widget is nested inside 
another scrollable widget.
flutter: If this widget is always nested in a scrollable widget there 
is no need to use a viewport because
flutter: there will always be enough vertical space for the children. 
In this case, consider using a Column
flutter: instead. Otherwise, consider using the "shrinkWrap" property 
(or a ShrinkWrappingViewport) to size
flutter: the height of the viewport to the sum of the heights of its children.

这是从堆栈跟踪的底部获取的:

flutter: The following RenderObject was being processed when the 
exception was fired:
flutter:   RenderViewport#cab62 NEEDS-LAYOUT NEEDS-PAINT
flutter:   creator: Viewport ← _ScrollableScope ← IgnorePointer- 
[GlobalKey#b71f9] ← Semantics ← Listener ←
flutter:   _GestureSemantics ← RawGestureDetector- 
[LabeledGlobalKey<RawGestureDetectorState>#d0420] ←
flutter:   _ScrollSemantics-[GlobalKey#02b55] ← Scrollable ← 
PrimaryScrollController ← ListView ← Column ← ⋯
flutter:   parentData: <none> (can use size)
flutter:   constraints: BoxConstraints(0.0<=w<=375.0, 0.0<=h<=Infinity)
flutter:   size: MISSING
flutter:   axisDirection: down
flutter:   crossAxisDirection: right
flutter:   offset: ScrollPositionWithSingleContext#892dc(offset: 0.0, 
range: null..null, viewport: null,
flutter:   ScrollableState, AlwaysScrollableScrollPhysics -> 
BouncingScrollPhysics, IdleScrollActivity#9455f,
flutter:   ScrollDirection.idle)
flutter:   anchor: 0.0
flutter: This RenderObject had the following descendants (showing up to 
depth 5):
flutter:   RenderSliverPadding#c8ab3 NEEDS-LAYOUT NEEDS-PAINT
flutter:     RenderSliverList#66f1b NEEDS-LAYOUT NEEDS-PAINT

我尝试将 ListView.builder 包装在 Expanded 小部件中,但这对我不起作用。 (这就是教程中正在做的事情)

我尝试将 Column 包装在 IntrinsicHeight 小部件中,但没有成功。

我设法解决此问题的唯一方法是将 ListView.builder 包装在具有设置高度属性的 Container 小部件中。但是在我看来,必须使用具有设定高度的 Container 并不合适。

如果需要,我可以尝试发布完整的代码以重新创建它。

【问题讨论】:

标签: flutter flutter-layout


【解决方案1】:

尝试使用 'Expanded' 而不是 Container 或其他布局:

Column(
        children: <Widget>[
          Expanded(
            //color: Colors.white,
            child:
            ListView.builder(
                itemCount: list.length,
                itemBuilder: (BuildContext context, int index) {
                  return ListTile(
                    contentPadding: EdgeInsets.all(10.0),
                    title: new Text('title'),
                    subtitle: new Text('sub title'),
                    onTap: () => clicked(list[index]['url']),
                    onLongPress: () => downloadAndStoreFile(list[index]['url'],
                        list[index]['name'], list[index]['title']),
                  );
                }),
          )
        ],
),

【讨论】:

    【解决方案2】:

    将此添加到 ListView.Builder =

    @override
    Widget build(BuildContext context) {
      return Column(
        children: <Widget>[
          Container(
            margin: EdgeInsets.all(10),
            child: ProductControl(_addProduct),
          ),
          ListView.builder(
          physics: NeverScrollableScrollPhysics(), ///
          shrinkWrap: true, ///
          scrollDirection: Axis.vertical, ///
            itemCount: _products.length,
            itemBuilder: (BuildContext context, int index) => Card(
                  child: Column(
                    children: <Widget>[
                      Image.asset('assets/food.jpg'),
                      Text(_products[index])
                    ],
                  ),
                ),
          )
        ],
      );
    }
    

    【讨论】:

    • 这在我的情况下没有解决任何问题。
    • 谢谢@Farick。 “shrinkWrap: true” 有效。
    【解决方案3】:

    我想我在发布问题后的最后一刻努力解决了这个问题。

    我的问题中没有显示的是另一段代码。

    基本上这就是我的代码的样子。

    body: Column(
          children: <Widget>[
            Column(
              children: <Widget>[
                Container(
                  margin: EdgeInsets.all(10),
                  child: ProductControl(_addProduct),
                ),
                ListView.builder(
                itemCount: _products.length,
                itemBuilder: (BuildContext context, int index) => Card(
                child: Column(
                  children: <Widget>[
                    Image.asset('assets/food.jpg'),
                    Text(_products[index])
                  ],
                ),
              ),
            )
          ],
        ),
       ],
     ),
    

    问题是我有一个 Column 作为直接子级,显然 ListView 不喜欢这样。所以通过删除第一个 Column 我可以将我的 ListView 包装在一个 Expanded 小部件中,一切正常。也许这可以帮助其他人。

    【讨论】:

      【解决方案4】:

      ColumnListView 都将它们的大小扩展到最大 => 错误

      3 个解决方案:

      1. ExpandedFlexible 包裹ListView
      Column(
        children: <Widget>[
          Expanded(
            child: ListView(),
          )
        ],
      )
      
      1. ContainerSizedBox 限制ListView 的高度
      Column(
        children: <Widget>[
          Container(
            height: 200,
            child: ListView(),
          )
        ],
      )
      
      1. 我最喜欢的解决方案:只需添加shrinkWrapNeverScrollableScrollPhysics()
      Column(
        children: <Widget>[
          ListView(
            shrinkWrap: true,
            physics: NeverScrollableScrollPhysics(),
          )
        ],
      )
      

      【讨论】:

        猜你喜欢
        • 2020-08-17
        • 1970-01-01
        • 2013-06-14
        • 2023-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-23
        相关资源
        最近更新 更多