代码之家  ›  专栏  ›  技术社区  ›  Marcelo Glasberg

在颤振中,如何解决“动画交叉渐变”的低效设计?

  •  3
  • Marcelo Glasberg  · 技术社区  · 6 年前

    一个问题 AnimatedCrossFade

    如果这些孩子中的一个(或两个)复杂而沉重,这是没有效率的。

    Builder

    AnimatedCrossFade(
        firstChild: widget1,
        secondChild: Builder(builder: widget2builder),
        duration: const Duration(milliseconds: 500),
        crossFadeState: toggle ? CrossFadeState.showFirst : CrossFadeState.showSecond,
    ),
    
    var widget2builder = (context) {
      print("Building widget 2");
      return Container(),
      );
    };
    

    但是,这个指纹 Building widget 2 马上,即使第一个小部件是正在显示的部件,因此根本不需要小部件2。

    import 'package:flutter/material.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 = true;
      }
    
      @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: UniqueKey(),
          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 widget2builder = (context) {
          print("Building widget 2.");
          return Container(
            key: UniqueKey(),
            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>[
                toggleButton,
                Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    const Text("Some text above."),
                    AnimatedCrossFade(
                      firstChild: widget1,
                      secondChild: Builder(builder: widget2builder),
                      duration: const Duration(milliseconds: 500),
                      crossFadeState: toggle ? CrossFadeState.showFirst : CrossFadeState.showSecond,
                    ),
                    const Text("Some text below."),
                  ],
                ),
              ],
            ),
          ),
        );
      }
    }
    

    如果你运行这个,你会看到的 构建控件2

    • 有什么原因吗 动画交叉淡入 正在构建它不使用的小部件?

    • 我如何防止这个问题和使用 动画交叉淡入 有效率吗?

    1 回复  |  直到 6 年前
        1
  •  3
  •   Rémi Rousselet    6 年前

    这是预期的行为。

    正如飞镖队所说,你应该期待 build 方法可随时调用。 建造 它的设计既便宜又没有副作用。

    Opacity “不透明度”(opacity)为0时,实际上会加快绘制过程(当完全不透明时,还会进行其他优化)。


    AnimatedSwitcher 在替换子对象时播放动画。

        2
  •  2
  •   Marcelo Glasberg    4 年前

    我想补充一下Rmi的回答,在提出这个问题之后,我发布了一个解决这个问题的包,名为 AnimatedSizeAndFade :

    https://pub.dev/packages/animated_size_and_fade

    它与其他类似的小部件相比如何:

    • 使用AnimatedCrossFade,必须同时保留firstChild和secondChild,而AnimatedSizeAndFade则不需要这样做。

    • 除非事先知道子对象的大小,否则AnimatedContainer也不起作用。