Flutter 条件动画

Flutter conditional animation

我有 Stack 5 Text 作为 children。每个 child 都包裹着一个 FadeTransition object。在 Stack 之外,我有 5 个 RaisedButton,每个映射到一个 Text。默认情况下,Text 1 的不透明度为 1,其余的不透明度为 0。单击按钮时,它映射的文本的不透明度变为 1,其余变为 0。 为此,我创建了 5 个不同的 AnimationController 并硬编码了一个很长的逻辑。 我不确定这是在 Flutter 中执行此操作的正确方法。 我相信一定有更简单的方法。 此外,这是一个简化的示例。我的实际应用中的问题甚至有复杂的条件。 (例如,当单击按钮 5 且布尔值 hasViewedText1 为真时,仅显示文本 2 和文本 3。)

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

class Test extends StatefulWidget {
  @override
  _State createState() {
    return _State();
  }
}

class _State extends State<Test> with TickerProviderStateMixin {
  AnimationController _animationController1;
  AnimationController _animationController2;
  AnimationController _animationController3;
  AnimationController _animationController4;
  AnimationController _animationController5;

  @override
  void initState() {
    super.initState();
    _animationController1 = new AnimationController(
      vsync: this,
      duration: new Duration(seconds: 1),
    );
    _animationController2 = new AnimationController(
      vsync: this,
      duration: new Duration(seconds: 1),
    );
    _animationController3 = new AnimationController(
      vsync: this,
      duration: new Duration(seconds: 1),
    );
    _animationController4 = new AnimationController(
      vsync: this,
      duration: new Duration(seconds: 1),
    );
    _animationController5 = new AnimationController(
      vsync: this,
      duration: new Duration(seconds: 1),
    );
    _everyThingBackward();
    _animationController1.forward();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: new AppBar(
        elevation: 0.5,
        title: new Text(
          "Testing views",
          style: Theme.of(context).textTheme.title,
        ),
      ),
//      body: _buildBodyAnimationTest(),
//      body:  _buildTuto(),
//      body: _builtLayoutBuilder(),
      body: _builtLayoutConditionalAnimation(),
    );
  }


  Widget _builtLayoutConditionalAnimation() {
    return new Column(
      children: <Widget>[
        new Column(
          children: <Widget>[
            new RaisedButton(child: new Text("Button 1"), onPressed: () {
              _everyThingBackward();
              _animationController1.forward();
            }),
            new RaisedButton(child: new Text("Button 2"), onPressed: () {
              _everyThingBackward();
              _animationController2.forward();
            }),
            new RaisedButton(child: new Text("Button 3"), onPressed: () {
              _everyThingBackward();
              _animationController3.forward();
            }),
            new RaisedButton(child: new Text("Button 4"), onPressed: () {
              _everyThingBackward();
              _animationController4.forward();
            }),
            new RaisedButton(child: new Text("Button 5"), onPressed: () {
              _everyThingBackward();
              _animationController5.forward();
            }),
          ],
        ),
        new Stack(
          children: <Widget>[
            FadeTransition(opacity: _animationController1,child: new Text('Text 1 is clicked')),
            FadeTransition(opacity: _animationController2,child: new Text('Text 2 is clicked')),
            FadeTransition(opacity: _animationController3,child: new Text('Text 3 is clicked')),
            FadeTransition(opacity: _animationController4,child: new Text('Text 4 is clicked')),
            FadeTransition(opacity: _animationController5,child: new Text('Text 5 is clicked')),
          ],
        ),
      ],
    );
  }

  void _everyThingBackward() {
    _animationController1.reverse();
    _animationController2.reverse();
    _animationController3.reverse();
    _animationController4.reverse();
    _animationController5.reverse();

  }
}

这可以通过使用 AnimatedSwitcher 小部件 link to docs.

变得更简单

这是一个完整的例子:

import 'package:flutter/material.dart';

void main() => runApp(App());

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(child: Center(child: Test())),
      ),
    );
  }
}

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

class _TestState extends State<Test> {
  Widget _child = Text(
    "No Button Tapped!",
    key: UniqueKey(),
  );

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        RaisedButton(
          child: Text("Button 1"),
          onPressed: () {
            setState(() {
              _child = Text(
                "Button 1 Tapped!",
                key: UniqueKey(),
              );
            });
          },
        ),
        RaisedButton(
          child: Text("Button 2"),
          onPressed: () {
            setState(() {
              _child = Text(
                "Button 2 Tapped!",
                key: UniqueKey(),
              );
            });
          },
        ),
        RaisedButton(
          child: Text("Button 3"),
          onPressed: () {
            setState(() {
              _child = Text(
                "Button 3 Tapped!",
                key: UniqueKey(),
              );
            });
          },
        ),
        AnimatedSwitcher(
          duration: Duration(milliseconds: 200),
          child: _child,
        ),
      ],
    );
  }
}

这篇中型文章也可能有用:https://medium.com/flutter-community/what-do-you-know-about-aniamtedswitcher-53cc3a4bebb8