【フラッター実戦】アニメーションシーケンス、共有アニメーション、ルーティングアニメーション

Lao Mengのガイド:この記事はFlutterアニメーションシリーズの4番目で、アニメーションシーケンス、共有アニメーション、ルーティングアニメーションについて紹介しています。

アニメーションシーケンス

結合されたアニメーションはFlutter Interval使用されInterval継承さCurveれます。使用方法は次のとおりです。

Animation _sizeAnimation = Tween(begin: 100.0, end: 300.0).animate(CurvedAnimation(
    parent: _animationController, curve: Interval(0.5, 1.0)));

_sizeAnimationアニメーションが0.5(半分)から最後まで開始することを示します。アニメーション期間が6秒の場合_sizeAnimation、3秒から開始します。

IntervalbeginendSP値が0.0〜1.0です。

以下は、最初に色の変更を実装し、次にサイズの変更を実装するためのコードです。

class AnimationDemo extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _AnimationDemo();
}

class _AnimationDemo extends State<AnimationDemo>
    with SingleTickerProviderStateMixin {
  AnimationController _animationController;
  Animation _colorAnimation;
  Animation _sizeAnimation;

  @override
  void initState() {
    _animationController =
        AnimationController(duration: Duration(seconds: 5), vsync: this)
    ..addListener((){setState(() {

    });});

    _colorAnimation = ColorTween(begin: Colors.red, end: Colors.blue).animate(
        CurvedAnimation(
            parent: _animationController, curve: Interval(0.0, 0.5)));

    _sizeAnimation = Tween(begin: 100.0, end: 300.0).animate(CurvedAnimation(
        parent: _animationController, curve: Interval(0.5, 1.0)));

    //开始动画
    _animationController.forward();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Container(
              height: _sizeAnimation.value,
              width: _sizeAnimation.value,
              color: _colorAnimation.value),
        ],
      ),
    );
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }
}

効果は次のとおりです。

同時にアニメーションを設定することもできIntervalますInterval(0.0, 1.0)両方の値を変更するだけです。

次のシーン、赤いボックス、アニメーション期間が6秒で、時間の最初の40%が100-> 200であり、200が20%の時間の間変更されず、最後の40%が200-> 300であると想像してください。この効果はTweenSequenceによって実現されます。コードは次のとおりです。

_animation = TweenSequence([
  TweenSequenceItem(
      tween: Tween(begin: 100.0, end: 200.0)
          .chain(CurveTween(curve: Curves.easeIn)),
      weight: 40),
  TweenSequenceItem(tween: ConstantTween<double>(200.0), weight: 20),
  TweenSequenceItem(tween: Tween(begin: 200.0, end: 300.0), weight: 40),
]).animate(_animationController);

weight各トゥイーンの重みを示します。

最終的な効果は次のとおりです。

アニメーションを共有する

ヒーローは、一般的に使用される遷移アニメーションです。ユーザーが画像をクリックして別のページに切り替えると、このページにもこの画像が表示されます。次に、ヒーローコンポーネントを使用することが適切です。ヒーローのレンダリングを見てみましょう:

上記の効果により実現されるリストページのコードは以下のとおりです。

class HeroDemo extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _HeroDemo();
}

class _HeroDemo extends State<HeroDemo> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GridView(
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3, crossAxisSpacing: 5, mainAxisSpacing: 3),
        children: List.generate(10, (index) {
          if (index == 6) {
            return InkWell(
              onTap: () {
                Navigator.push(
                    context,
                    new MaterialPageRoute(
                        builder: (context) => new _Hero1Demo()));
              },
              child: Hero(
                tag: 'hero',
                child: Container(
                  child: Image.asset(
                    'images/bird.png',
                    fit: BoxFit.fitWidth,
                  ),
                ),
              ),
            );
          }
          return Container(
            color: Colors.red,
          );
        }),
      ),
    );
  }
}

2ページ目のコードは次のとおりです。

class _Hero1Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Container(
          alignment: Alignment.topCenter,
          child: Hero(
            tag: 'hero',
            child: Container(
              child: Image.asset(
                'images/bird.png',
              ),
            ),
          )),
    );
  }
}

どちらのページにもヒーローコントロールがあり、tagパラメーターは同じです。

ルーティングアニメーション

遷移は、現在のページから別のページにジャンプすることです。ジャンプページは、次のようにFlutterのナビゲーターを介して新しいページにジャンプします。

Navigator.push(context, MaterialPageRoute(builder: (context) {
  return _TwoPage();
}));

前のページに戻る:

Navigator.pop(context);

Flutterには、2つのトランジションアニメーション、つまりMaterialPageRouteCupertinoPageRouteが用意されています。MaterialPageRouteは、プラットフォームに応じて異なる効果を表示します。Android効果は下から上、iOS効果は左から右です。CupertinoPageRouteは、プラットフォームに関係なく左から右です。

MaterialPageRouteの使用例は次のとおりです。

class NavigationAnimation extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: OutlineButton(
          child: Text('跳转'),
          onPressed: () {
            Navigator.push(context, CupertinoPageRoute(builder: (context) {
              return _TwoPage();
            }));
          },
        ),
      ),
    );
  }
}

class _TwoPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Container(
        color: Colors.blue,
      ),
    );
  }
}

iOS効果:

トランジションアニメーションをカスタマイズするにはどうすればよいですか?

コンポーネントのカスタマイズは同じです。システムが類似している場合は、ソースコードの実装方法を確認し、テンプレートに従ってコンポーネントをカスタマイズします。

トピックに戻り、MaterialPageRouteの継承関係を確認します。

PageRouteの継承関係:

MaterialPageRouteとCupertinoPageRouteはどちらもPageRouteを継承しているため、フォーカスはPageRouteにあります。Pag​​eRouteは抽象クラスであり、そのサブクラスにもPageRouteBuilderがあります。名前を見ると、これがカスタムアニメーション効果であることがわかります。Pag​​eRouteBuilderソースコード:

pageBuilder ジャンプするページを示します。

transitionsBuilder ページのアニメーション効果、デフォルト値コードを示します。

Widget _defaultTransitionsBuilder(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
  return child;
}

ソースコードを通じて発見され、デフォルトではアニメーション効果はありません。

カスタムの遷移アニメーションを変更する必要がtransitionsBuilderあるだけです。

Navigator.push(
    context,
    PageRouteBuilder(pageBuilder: (
      BuildContext context,
      Animation<double> animation,
      Animation<double> secondaryAnimation,
    ) {
      return _TwoPage();
    }, transitionsBuilder: (BuildContext context,
        Animation<double> animation,
        Animation<double> secondaryAnimation,
        Widget child) {
      return SlideTransition(
        position: Tween(begin: Offset(-1, 0), end: Offset(0, 0))
            .animate(animation),
        child: child,
      );
    }));

簡単に使用できるようにカプセル化します。

class LeftToRightPageRoute extends PageRouteBuilder {
  final Widget newPage;

  LeftToRightPageRoute(this.newPage)
      : super(
          pageBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
          ) =>
              newPage,
          transitionsBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
            Widget child,
          ) =>
              SlideTransition(
            position: Tween(begin: Offset(-1, 0), end: Offset(0, 0))
                .animate(animation),
            child: child,
          ),
        );
}

使用する:

Navigator.push(context, LeftToRightPageRoute(_TwoPage()));

これらのパンペインティングだけでなく、以前に学習した回転やズームなどのアニメーションも、SlideTransitionを直接置き換えることができます。

上記のアニメーションは新しいページをアニメーション化するだけです。現在のページが新しいページによって上から排出される効果を達成したい場合、実装は次のとおりです。

class CustomPageRoute extends PageRouteBuilder {
  final Widget currentPage;
  final Widget newPage;

  CustomPageRoute(this.currentPage, this.newPage)
      : super(
          pageBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
          ) =>
              currentPage,
          transitionsBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
            Widget child,
          ) =>
              Stack(
            children: <Widget>[
              SlideTransition(
                position: new Tween<Offset>(
                  begin: const Offset(0, 0),
                  end: const Offset(0, -1),
                ).animate(animation),
                child: currentPage,
              ),
              SlideTransition(
                position: new Tween<Offset>(
                  begin: const Offset(0, 1),
                  end: Offset(0, 0),
                ).animate(animation),
                child: newPage,
              )
            ],
          ),
        );
}

本質は、2つのページをアニメーション化することです。

Navigator.push(context, CustomPageRoute(this, _TwoPage()));

カスタムルーティングアニメーションに加えて、Flutter 1.17リリース会議では、Flutterチームが新しいアニメーションパッケージもリリースしました。これは、新しいマテリアルモーション仕様を実装する事前に作成されたアニメーションを提供します。

それは一連のアニメーション、いくつかの効果を提供します:

詳細:https : //juejin.im/post/6847902223909781511

と通信する

Laomeng Flutterブログアドレス(330コントロールの使用):http ://laomengit.com

Flutter交換グループ(WeChat:laomengit)へようこそ。パブリックアカウント[Lao Meng Flutter]に従ってください。

おすすめ

転載: blog.csdn.net/mengks1987/article/details/108212636