web-dev-qa-db-ja.com

フラッターでヒーローアニメーションの速度を変更する方法

Flutterのウェブサイト の指示に従って、シンプルなヒーローアニメーションを作成しました

手順で説明されているように機能しますが、私の場合、最初の画面から2番目の画面までずっとゆっくりとアニメートしたいと思います。このアニメーションの速度を変更する方法を知っている人はいますか?

15
Asger Lorenzen

遷移速度を変更するには、 PageRoute 遷移時間を調整する必要があります(@diegoveloperによって既に指摘されています)。

デフォルトの遷移を保持したい場合は、 MaterialPageRoute を実装するクラスを作成できます。すでに独自のトランジションがある場合、またはトランジションを作成する場合は、 PageRouteBuilder を使用して簡単に独自のトランジションを構築できます。 transitionDurationを調整するだけです。

次に、PageRouteBuilderを使用した小さなスタンドアロンの例を示します。

Transition Demo

import 'package:flutter/material.Dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Page1(),
    );
  }
}

class Page1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: <Widget>[
            RaisedButton(
              child: Text('Page2'),
              onPressed: () => Navigator.Push(
                  context,
                  PageRouteBuilder(
                      transitionDuration: Duration(seconds: 2),
                      pageBuilder: (_, __, ___) => Page2())),
            ),
            Hero(tag: 'home', child: Icon(Icons.home))
          ],
        ),
      ),
    );
  }
}

class Page2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Hero(
          tag: 'home',
          child: Icon(
            Icons.home,
          ),
        ),
      ),
    );
  }
}
7
Niklas

1.可能な解決策

これを達成する唯一の方法は、PageRoute遷移時間を変更することによるものではないと思います。 AnimationControllerを使用しても同じ効果が得られると思います。この答えは主に Angela YuのThe Complete 2019 Flutter Development Bootcamp with Dart の講義#149と#150から来ています。

  1. 画面をStatefulWidgetに変えます。
  2. アニメーションを1つだけ使用している場合は、with SingleTickerProviderStateMixinを状態クラスに追加します。
  3. 状態クラス内にコントローラーを作成します。
  4. アニメーションが画面の初期化に表示されることになっている場合は、controllerメソッド内でinitStateを使用します。
    • コントローラーにはdurationと呼ばれるプロパティがあるため、好みに応じて変更できます。

2.どのように見えるか

最後に、すべてが次のように見えるはずです。

class _NewScreenState extends State<HomeScreen> 
  with SingleTickerProviderStateMixin{

  AnimationController controller;

  @override
  void initState() {
    super.initState();

    controller = AnimationController(
      duration: Duration(seconds: 1),
      vsync: this,
    );

    controller.forward();

    controller.addListener((){
      setState(() {

      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return ...
  • vsyncは、必須の(@required)パラメータであり、状態(インスタンス)オブジェクト自体(通常)を取ります。
  • addListenersetStateは、将来のある時点でcontrollercontroller.value)の値を使用する場合に存在します—たとえば、高さの変更アイコンのheight: finalHeight * controller.valueのようなもの。
  • この画面への移行のために、私は単にFlatButtonNavigator.pushNamedとともに使用していますが、特別なことは何もありません。

3.その他の重要な情報

  1. 後で画面を変更しても、controllerは引き続きアクティブです。したがって、バックグラウンドでループするアニメーションがある場合は、画面を変更するときにそれをdisposeすることをお勧めします。これにより、電話のリソースを無駄にしません。それでもう。これは次のようにして達成できます:
    @override
    void dispose() {
      controller.dispose();
      super.dispose();
    }
    
  2. アニメーションの実行方法、またはアニメーションの実行方法をカスタマイズすることもできます。 1つのオプションは、CurvedAnimation。を使用することです。
    1. controllerの真下でAnimation animation;を宣言します。
    2. controllerの下、initState内に次の行を追加します:
      animation = CurvedAnimation( // the controller can't have upperBound > 1
        parent: controller, // the controller you created
        curve: Curves.decelerate,
      );
      
  3. Flutterでアニメーション化するもう1つの便利な方法は、TweenAnimationsを使用することです。たとえば、between色に移行する場合は、ColorTweencontrollerの下、initState):
    animation = ColorTween(
      begin: Colors.red,
      end: Colors.blue,
    ).animate(controller);
    
0
Philippe Fanaro