【问题标题】:Flutter - Animate change on height when hide one of Column childrenFlutter - 隐藏 Column 孩子之一时动画高度变化
【发布时间】:2020-04-04 21:05:23
【问题描述】:

我在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,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

【问题讨论】:

    标签: flutter flutter-animation


    【解决方案1】:

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

    在这里,我稍微更改了您的代码。现在可以正常使用了。

        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,
                      ),
                    ),
                  ],
                ),
              ),
            );
          }
        }
    

    【讨论】:

    • height: null 是绝对的赢家,谢谢