Flutter - 隐藏列子项之一时高度的动画变化

Osa*_* Na 9 flutter flutter-animation

我在Column小部件中有两个孩子,第一个是简单的Container,第二个是Expanded小部件。用户可以隐藏/显示第一个Container. 在这种情况下,我需要在两个小部件上应用动画,因此第一个容器的高度应自动减小,第二个小部件的高度应逐渐增加,直到填满整个空间。

我测试使用AnimatedContainer,但它需要指定其前后的高度,这是我不知道的。

请问有什么建议吗?

class ViewerPage extends StatefulWidget {
  @override
  _ViewerPageState createState() => _ViewerPageState();
}

class _ViewerPageState extends State<ViewerPage> {
  bool visible = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Example"),
      ),
      bottomNavigationBar: BottomAppBar(
        child: Row(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: <Widget>[
            IconButton(
              icon: Icon(Icons.show_chart),
              onPressed: () {
                setState(() {
                  visible = !visible;
                });
              },
            ),
          ],
        ),
      ),
      body: Container(
        child: Column(
          children: <Widget>[
            Visibility(
              visible: visible,
              child: Container(
                  child: Text("This Container can be visible or hidden"),
                  color: Colors.red),
            ),
            Expanded(
              child: ListView.builder(
                itemBuilder: (context, index) => Text("Item ..."),
                itemCount: 20,
              ),
            ),
          ],
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

Raf*_*ahi 16

很简单,使用 AnimatedSize,并删除 Visibility。AnimatedSize 自行计算高度。所以你不需要知道之前和之后的尺寸。

只需传递 null 表示动态高度,传递 0 表示不可见。AnimatedSize 将处理动画

height: visible? null : 0.0,
Run Code Online (Sandbox Code Playgroud)

在这里,我稍微改变了你的代码。现在效果很好。

    import 'package:flutter/material.dart';

    class Test extends StatefulWidget {
      @override
      _TestState createState() => _TestState();
    }

    class _TestState extends State<Test> with SingleTickerProviderStateMixin{

      bool visible = true;
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("Example"),
          ),
          bottomNavigationBar: BottomAppBar(
            child: Row(
              mainAxisSize: MainAxisSize.max,
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: <Widget>[
                IconButton(
                  icon: Icon(Icons.show_chart),
                  onPressed: () {
                    setState(() {
                      visible = !visible;
                    });
                  },
                ),
              ],
            ),
          ),
          body: Container(
            child: Column(
              children: <Widget>[
                AnimatedSize(
                  duration: Duration(seconds: 1),
                  child: Container(
                    height: visible? null : 0.0,
                    child: Text("This Container can be visible or hidden"),
                    color: Colors.red
                  ), 
                  vsync: this,
                ),
                Expanded(
                  child: ListView.builder(
                    itemBuilder: (context, index) => Text("Item ..."),
                    itemCount: 20,
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
Run Code Online (Sandbox Code Playgroud)


小智 5

接受的解决方案从技术上讲并没有隐藏该项目,它只是折叠到高度为零,我遇到了这样的情况:当 ListView 同级向下滑动时会出现一个小部件(图标)。

我推荐以下解决方案:

AnimatedSize(
duration: const Duration(milliseconds: 500),
child: visible ? Container( child: Text("This Container can be visible or hidden"), color: Colors.red) : const SizedBox(),),

Run Code Online (Sandbox Code Playgroud)