动画容器:RenderFlex 在底部溢出 154 像素

Yan*_*n39 3 flutter flutter-layout flutter-animation

在设置不同的内容高度时调整动画容器的大小时遇到​​问题。

它在调整大小时抛出异常:

????????? 渲染库捕获的异常 ????????

在布局期间抛出了以下断言:

RenderFlex 在底部溢出了 154 个像素。

动画容器溢出

这是重现问题的最小示例(在我的实际应用程序中要复杂得多,但您明白了):

bool expanded;

initState() {
  super.initState();
  expanded = false;
}

void _toggleMode() {
  setState(() {
    expanded = !expanded;
  });
}

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text("Test")),
    body: AnimatedContainer(
      height: expanded ? 230 : 70,
      duration: Duration(milliseconds: 800),
      child: Column(
        children: <Widget>[
          Expanded(
            child: PageView.builder(
              itemBuilder: (context, position) {
                return expanded
                    ? Column(
                        children: <Widget>[
                          Container(height: 40, color: Colors.blue),
                          Container(height: 40, color: Colors.blue[400]),
                          Container(height: 40, color: Colors.blue[300]),
                          Container(height: 40, color: Colors.blue[200]),
                          Container(height: 40, color: Colors.blue[100]),
                        ],
                      )
                    : Column(
                        children: <Widget>[
                          Container(height: 40, color: Colors.blue),
                        ],
                      );
              },
            ),
          ),
          InkWell(onTap: _toggleMode, child: expanded ? Icon(Icons.keyboard_arrow_up) : Icon(Icons.keyboard_arrow_down))
        ],
      ),
    ),
  );
}
Run Code Online (Sandbox Code Playgroud)

在两种模式下(扩展与否),内容都适合容器(无溢出),问题仅在调整大小时出现。

当然,没有动画的基本容器不会发生问题。

我该如何处理?

Sae*_*bil 9

发生这种情况是因为您检查了已扩展,然后在容器达到其最终大小之前立即返回容器

一种解决方法是使用 ListView 更改更大的列NeverScrollableScrollPhysics()

编辑:您甚至不需要再检查是否展开,您将获得正确的动画

 bool expanded;

  initState() {
    super.initState();
    expanded = false;
  }

  void _toggleMode() {
    setState(() {
      expanded = !expanded;
    });
  }

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Test")),
      body: AnimatedContainer(
        height: expanded ? 230 : 70,
        duration: Duration(milliseconds: 800),
        child: Column(
          children: <Widget>[
            Expanded(
              child: PageView.builder(
                itemBuilder: (context, position) {
                  return ListView(
                    physics: NeverScrollableScrollPhysics(),
                        children: <Widget>[
                    Column(
                      children: <Widget>[
                          Container(height: 40, color: Colors.blue),
                          Container(height: 40, color: Colors.blue[400]),
                          Container(height: 40, color: Colors.blue[300]),
                          Container(height: 40, color: Colors.blue[200]),
                          Container(height: 40, color: Colors.blue[100]),
                      ],
                    ),
                  ],
                      );
//                      : Column(
//                    children: <Widget>[
//                      Container(height: 40, color: Colors.blue),
//                    ],
//                  );
                },
              ),
            ),
            InkWell(onTap: _toggleMode, child: expanded ? Icon(Icons.keyboard_arrow_up) : Icon(Icons.keyboard_arrow_down))
          ],
        ),
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

  • 谢谢,好技巧!正如您所说,这是一种解决方法,但它确实有效。实际上,我不仅有 2 个状态(展开或未展开),而是具有不同高度的多个内容,因此我必须将我的 switch/case 提取到一个函数,然后按照您的建议用不可滚动的可滚动小部件 :D 包装它。我使用了 `SingleChildScrollView` 而不是 `ListView`,我猜这可能消耗更少(?)。奇迹般有效。 (2认同)