在Flutter中,如何更改某些小部件并使其动画成其新大小? [英] In Flutter, how can I change some widget and see it animate to its new size?

查看:186
本文介绍了在Flutter中,如何更改某些小部件并使其动画成其新大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想更改某个小部件的子级,然后使其动画化为新子级的高度,同时还带有淡入淡出过渡.

I would like to change the child of some widget, and then see it animate to the new child's height, also with a fade transition.

我可以用AnimatedCrossFade来做到这一点,但是我必须同时保留firstChildsecondChild,而我不能.

I can do that with AnimatedCrossFade, but then I must keep both firstChild and secondChild, which I cannot.

如果我使用AnimatedSwitcher,它可以让我简单地更改其子级,但是它只会设置淡入淡出的动画效果,而不是大小.

If I use AnimatedSwitcher, it lets me simply change its child, but then it only animates the fade, not the size.

AnimatedContainer也不起作用,因为我事先不知道孩子的大小.

The AnimatedContainer also doesn't work, since I don't know the size of the children in advance.

我缺少一些可以满足我需要的小部件吗?如果没有,该如何在不使用AnimationController的情况下做到这一点?

Is there some widget I am missing that does what I need, and if not, how can I do that without resorting to AnimationControllers?

推荐答案

这解决了问题:

https://pub.dev/packages/animated_size_and_fade

它可以同时淡化和设置大小的动画,而不必指定两个子对象.您还可以分别为淡入淡出和大小定义持续时间和曲线.

It fades and animates the size at the same time, without having to specify two children. You can also define a duration and curve for both the fade and the size, separately.

像这样使用它:

bool toggle=true; 
Widget widget1 = ...;
Widget widget2 = ...;

AnimatedSizeAndFade(
    vsync: this,
    child: toggle ? widget1 : widget2,
),

注意:如果您想使用上面的代码,请务必阅读文档:

Note: If you want to use the above code, please do read the documentation:

  • 旧"和新"子级必须具有相同的宽度,但可以具有不同的高度.

  • The "old" and the "new" child must have the same width, but can have different heights.

如果新"子代与旧"子代具有相同的小部件类型,但具有不同的参数,则AnimatedSizeAndFade将不会在它们之间进行转换,因为就框架而言,它们是相同的窗口小部件,并且可以使用新参数更新现有窗口小部件.要强制发生过渡,请设置Key(通常为ValueKey),该参数将获取任何会改变小部件在您希望视为唯一的子小部件上的外观的小部件数据.

If the "new" child is the same widget type as the "old" child, but with different parameters, then AnimatedSizeAndFade will NOT do a transition between them, since as far as the framework is concerned, they are the same widget, and the existing widget can be updated with the new parameters. To force the transition to occur, set a Key (typically a ValueKey taking any widget data that would change the visual appearance of the widget on each child widget that you wish to be considered unique.

这是一个可运行的示例:

This is a runnable example:

import 'package:flutter/material.dart';
import 'package:widgets/widgets.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
  bool toggle;

  @override
  void initState() {
    super.initState();
    toggle = false;
  }

  @override
  Widget build(BuildContext context) {
    var toggleButton = Padding(
      padding: const EdgeInsets.all(8.0),
      child: MaterialButton(
        child: const Text("Toggle"),
        color: Colors.grey,
        onPressed: () {
          setState(() {
            toggle = !toggle;
          });
        },
      ),
    );

    var widget1 = Container(
      key: ValueKey("first"),
      color: Colors.blue,
      width: 200.0,
      child: const Text(
        "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt "
            "ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation "
            "ullamco laboris nisi ut aliquip ex ea commodo consequat.",
      ),
    );

    var widget2 = Container(
      key: ValueKey("second"),
      color: Colors.red,
      width: 200.0,
      child: const Text(
        "I am ready for my closeup.",
      ),
    );

    return MaterialApp(
      home: Material(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Container(height: 100.0),
            toggleButton,
            Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                const Text("Some text above."),
                AnimatedSizeAndFade(
                  vsync: this,
                  child: toggle ? widget1 : widget2,
                  fadeDuration: const Duration(milliseconds: 300),
                  sizeDuration: const Duration(milliseconds: 600),
                ),
                const Text("Some text below."),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

这篇关于在Flutter中,如何更改某些小部件并使其动画成其新大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆