Flutter:在动画的、定位的容器中获取 ListView,作为堆栈的一部分

Posted

技术标签:

【中文标题】Flutter:在动画的、定位的容器中获取 ListView,作为堆栈的一部分【英文标题】:Flutter: getting ListView in animated, positioned container being part of a stack 【发布时间】:2020-12-29 04:40:18 【问题描述】:

也许你们中的某个人已经遇到过这些问题。我花了很多时间试图将 ListView(我也尝试过 ExpansionPanelList)放入一个容器中,该容器从右边缘平移到现有小部件的屏幕(帮助菜单)中。我已经创建了一个从基本 ListView 开始的模型,然后再次逐个添加功能。但是现在我被卡住了,错误消息对我没有多大帮助。

一旦我添加了 AnimatedPositioned,就会抛出这些异常。主要信息似乎是 constraints.hasBoundedWidth': is not true.

════════ Exception caught by rendering library ═════════════════════════════════════════════════════
The following assertion was thrown during performLayout():
'package:flutter/src/rendering/viewport.dart': Failed assertion: line 1754 pos 16: 'constraints.hasBoundedWidth': is not true.


Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new?template=BUG.md

The relevant error-causing widget was: 
  ListView file:///Users/holger/IdeaProjects/math/lib/tmp.dart:496:40
When the exception was thrown, this was the stack: 
#2      RenderShrinkWrappingViewport.performLayout (package:flutter/src/rendering/viewport.dart:1754:16)
#3      RenderObject.layout (package:flutter/src/rendering/object.dart:1775:7)
#4      RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:115:13)
#5      RenderObject.layout (package:flutter/src/rendering/object.dart:1775:7)
#6      RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:115:13)
...
The following RenderObject was being processed when the exception was fired: RenderShrinkWrappingViewport#a1875 relayoutBoundary=up7 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
...  needs compositing
...  parentData: <none> (can use size)
...  constraints: BoxConstraints(0.0<=w<=Infinity, 0.0<=h<=716.8)
...  size: MISSING
...  axisDirection: down
...  crossAxisDirection: right
...  offset: ScrollPositionWithSingleContext#20c01(offset: 0.0, range: null..null, viewport: null, ScrollableState, AlwaysScrollableScrollPhysics -> BouncingScrollPhysics, IdleScrollActivity#3e990, ScrollDirection.idle)
RenderObject: RenderShrinkWrappingViewport#a1875 relayoutBoundary=up7 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
  needs compositing
  parentData: <none> (can use size)
  constraints: BoxConstraints(0.0<=w<=Infinity, 0.0<=h<=716.8)
  size: MISSING
  axisDirection: down
  crossAxisDirection: right
  offset: ScrollPositionWithSingleContext#20c01(offset: 0.0, range: null..null, viewport: null, ScrollableState, AlwaysScrollableScrollPhysics -> BouncingScrollPhysics, IdleScrollActivity#3e990, ScrollDirection.idle)
...  child 0: RenderSliverPadding#078d5 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
...    parentData: layoutOffset=None
...    constraints: MISSING
...    geometry: null
...    padding: EdgeInsets.zero
...    textDirection: ltr
...    child: RenderSliverList#fd0a6 NEEDS-LAYOUT NEEDS-PAINT
...      parentData: paintOffset=Offset(0.0, 0.0)
...      constraints: MISSING
...      geometry: null
...      no children current live
════════════════════════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════════════════════════
RenderBox was not laid out: RenderShrinkWrappingViewport#a1875 relayoutBoundary=up7 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1713 pos 12: 'hasSize'
The relevant error-causing widget was: 
  ListView file:///Users/holger/IdeaProjects/math/lib/tmp.dart:496:40

异常消息的下部重复多次,可能每个动画步骤重复一次。然后消息以以下消息结束,其中引用容器是 AnimatedPositiones > IgnorePointer > Container

════════ Exception caught by rendering library ═════════════════════════════════════════════════════
The following assertion was thrown during paint():
RenderBox was not laid out: RenderDecoratedBox#a83d8
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1713 pos 12: 'hasSize'


Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new?template=BUG.md

The relevant error-causing widget was: 
  Container file:///Users/holger/IdeaProjects/math/lib/tmp3.dart:474:32
When the exception was thrown, this was the stack: 
#2      RenderBox.size (package:flutter/src/rendering/box.dart:1713:12)
#3      RenderDecoratedBox.paint (package:flutter/src/rendering/proxy_box.dart:2067:12)
#4      RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2307:7)
#5      PaintingContext.paintChild (package:flutter/src/rendering/object.dart:191:13)
#6      RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:133:15)
...
The following RenderObject was being processed when the exception was fired: RenderDecoratedBox#a83d8
...  needs compositing
...  parentData: <none> (can use size)
...  constraints: BoxConstraints(w=331.2, h=716.8)
...  size: MISSING
...  decoration: BoxDecoration
...    color: Color(0xffffffff)
...  configuration: ImageConfiguration(bundle: PlatformAssetBundle#b6597(), devicePixelRatio: 3.0, locale: en_US, textDirection: TextDirection.ltr, platform: ios)
RenderObject: RenderDecoratedBox#a83d8
  needs compositing
  parentData: <none> (can use size)
  constraints: BoxConstraints(w=331.2, h=716.8)
  size: MISSING
  decoration: BoxDecoration
    color: Color(0xffffffff)
  configuration: ImageConfiguration(bundle: PlatformAssetBundle#b6597(), devicePixelRatio: 3.0, locale: en_US, textDirection: TextDirection.ltr, platform: iOS)
...  child: RenderFlex#28045 NEEDS-PAINT
...    needs compositing
...    parentData: <none> (can use size)
...    constraints: BoxConstraints(w=331.2, h=716.8)
...    size: MISSING
...    direction: horizontal
...    mainAxisAlignment: start
...    mainAxisSize: max
...    crossAxisAlignment: center
...    textDirection: ltr
...    verticalDirection: down
...    textBaseline: alphabetic
...    child 1: RenderPadding#b537d relayoutBoundary=up1 NEEDS-PAINT
...      parentData: offset=Offset(0.0, 0.0); flex=null; fit=null (can use size)
...      constraints: BoxConstraints(0.0<=w<=Infinity, 0.0<=h<=716.8)
...      size: Size(59.0, 716.8)
...      padding: EdgeInsets(3.0, 0.0, 0.0, 0.0)
...      textDirection: ltr
...      child: RenderFlex#4c2a2 relayoutBoundary=up2 NEEDS-PAINT
...        parentData: offset=Offset(3.0, 0.0) (can use size)
...        constraints: BoxConstraints(0.0<=w<=Infinity, 0.0<=h<=716.8)
...        size: Size(56.0, 716.8)
...        direction: vertical
...        mainAxisAlignment: spaceEvenly
...        mainAxisSize: max
...        crossAxisAlignment: center
...        verticalDirection: down
...        child 1: RenderSemanticsGestureHandler#c07e2 relayoutBoundary=up3 NEEDS-PAINT
...          parentData: offset=Offset(0.0, 330.4); flex=null; fit=null (can use size)
...          constraints: BoxConstraints(unconstrained)
...          size: Size(56.0, 56.0)
...          gestures: tap
...    child 2: _RenderScrollSemantics#80100 relayoutBoundary=up1 NEEDS-PAINT
...      needs compositing
...      parentData: offset=Offset(0.0, 0.0); flex=null; fit=null (can use size)
...      constraints: BoxConstraints(0.0<=w<=Infinity, 0.0<=h<=716.8)
...      semantic boundary
...      size: MISSING
...      child: RenderPointerListener#695c7 relayoutBoundary=up2 NEEDS-PAINT
...        needs compositing
...        parentData: <none> (can use size)
...        constraints: BoxConstraints(0.0<=w<=Infinity, 0.0<=h<=716.8)
...        size: MISSING
...        behavior: deferToChild
...        listeners: signal
...        child: RenderSemanticsGestureHandler#db442 relayoutBoundary=up3 NEEDS-PAINT
...          needs compositing
...          parentData: <none> (can use size)
...          constraints: BoxConstraints(0.0<=w<=Infinity, 0.0<=h<=716.8)
...          size: MISSING
...          gestures: <none>
════════════════════════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════════════════════════
RenderBox was not laid out: RenderDecoratedBox#a83d8
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1713 pos 12: 'hasSize'
The relevant error-causing widget was: 
  Container file:///Users/holger/IdeaProjects/math/lib/tmp3.dart:474:32

ListView 是这样的,它显示了不同标签的标题,每个标签都可以展开以显示详细信息。

AnimatedPositioned(duration: Duration(milliseconds: 800),
                  left: _drawerLeft,
                  top:5,
                      child: IgnorePointer(ignoring: (_drawerLeft <= MediaQuery.of(context).size.width / 3 ? false:true),
                        child: Container(
                          height:0.8*1 * MediaQuery.of(context).size.height, width:0.8 * MediaQuery.of(context).size.width,
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.start,
                            children: <Widget>[                           
                                    CupertinoButton(
                                      child: Icon(fwdBtn),
                                      onPressed: () 
                                        setState(() 
                                          _drawerLeft = 1 * MediaQuery.of(context).size.width;
                                          controller.reverse();
                                        );
                                      ,
                                    ),
                              ListView.builder(
                                scrollDirection: Axis.vertical,
                                shrinkWrap: true,
                                itemCount: usedTagData.length, itemBuilder: (BuildContext context, int index) 
                                  return Column(
                                    children: <Widget>[
                                      Row(
                                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                        children: <Widget>[
                                          Text(usedTagData[index].header, style: TextStyle(color: CupertinoColors.link)),
                                          CupertinoButton(
                                            child: Icon(dwnBtn),
                                            onPressed: () 
                                              setState(() 
                                                usedTagData[index].isExpanded = !usedTagData[index].isExpanded;
                                              );
                                            ,
                                          ),
                                        ],
                                      ),
                                      (usedTagData[index].isExpanded ?
                                        Text(usedTagData[index].content)
                                      :
                                        Container()
                                      ),
                                    ]
                                  );
                                
                             ),
                            ],
                          ),
                      )),
                )

AnimatedPositioned 是一个小部件

              return Container(
                height: MediaQuery.of(context).size.height,
                child: Stack(
                fit: StackFit.expand,
                children: <Widget>[

您是否知道如何继续进行此操作或异常消息是否为您提供任何提示?

【问题讨论】:

我现在可以使用它了,但是在设计上有一些折衷。在上面的代码中,我有 AnimatedPositioned > Row > 按钮,ListView。如果我将行更改为列,它会起作用。任何想法如何让它与 Row 一起工作将不胜感激 让它与行一起工作的唯一方法是设置预定义的宽度。您的列表视图试图无限扩展,因此您应该通过设置预定义的宽度来限制它。 成功了。如果有人遇到这个问题,我的问题和我上面的评论之间解决了进一步的问题,其中将 AnimatedPositioned 转换为 Tween 并仅在幻灯片完全提取后才显示幻灯片的内容。 @Uni,很高兴将您的评论标记为答案。 谢谢。祝你的 Flutter 项目好运@w461 :) 【参考方案1】:

ListViewRow 一起工作的唯一方法是设置预定义的宽度。您的 ListView 尝试无限扩展,因此您应该通过设置预定义的宽度来限制它。 这是一个例子:

Row(
 children:[
  SizedBox(
    width:200,
    child:ListView()
  ),
]),

【讨论】:

以上是关于Flutter:在动画的、定位的容器中获取 ListView,作为堆栈的一部分的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 中使用 Android 滚动行为为容器移动设置动画?

如何在 Flutter 中为容器的底部边框设置动画?

在 Flutter 中,您如何制作动画以将容器从 0 高度扩展到其内容的高度?

Flutter Container 在 Row 小部件内定位或对齐

使用偏移量的容器动画 - Flutter

Flutter 动画无法正常工作