【问题标题】:How to change speed of a hero animation in flutter如何在颤动中改变英雄动画的速度
【发布时间】:2019-05-12 15:12:29
【问题描述】:

我按照Flutter's website的指示制作了简单的英雄动画

它按照说明中的说明工作,但就我而言,我希望它从第一个屏幕到第二个屏幕的动画速度要慢得多。有谁知道如何改变这个动画的速度?

【问题讨论】:

  • 这取决于 PageRoute 过渡持续时间,因此您必须创建/实现自己的 PageRoute
  • 您可能会发现此解决方案很有帮助here

标签: flutter flutter-layout flutter-animation


【解决方案1】:

要修改转换速度,您必须调整PageRoute 转换持续时间(正如@diegoveloper 已经指出的那样)。

如果你想保持默认转换,你可以创建一个实现MaterialPageRoute的类。如果您已经有自己的过渡或想要创建一个,您可以使用PageRouteBuilder 轻松构建自己的过渡。只需调整transitionDuration

这是一个小的独立示例,使用 PageRouteBuilder

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,
          ),
        ),
      ),
    );
  }
}

【讨论】:

    【解决方案2】:

    1。一个可能的解决方案

    我认为实现此目的的唯一方法是通过更改PageRoute 转换持续时间。我认为您也可以通过使用AnimationController 来达到相同的效果——这个答案主要来自Angela Yu's The Complete 2019 Flutter Development Bootcamp with Dart 的#149 和#150 讲座。

    1. 把你的屏幕变成StatefulWidget
    2. 如果您只使用一个动画,请将with SingleTickerProviderStateMixin 添加到您的状态类中。
    3. 在状态类中创建一个控制器。
    4. 如果您的动画应该出现在屏幕的初始化上,请在initState 方法中使用controller
      • 控制器有一个名为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 如果您希望在将来的某个时候使用 controller (controller.value) 的值 - 例如,用 height: finalHeight * controller.value 之类的东西更改图标的高度。
    • 为了过渡到这个屏幕,我只是使用FlatButtonNavigator.pushNamed,没什么特别的。

    3。一些额外的重要信息

    1. 即使您稍后更改屏幕,controller 仍将处于活动状态。因此,如果您在后台有一个循环动画,最好在更改屏幕时dispose它,这样您就不会再浪费手机资源了。这可以通过以下方式实现:
      @override
      void dispose() {
        controller.dispose();
        super.dispose();
      }
      
    2. 您还可以自定义如何动画的运行方式或执行方式。一种选择是使用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 中制作动画的另一种有用方法是使用TweenAnimations。例如,如果您想在 之间转换 颜色,您可以使用 ColorTween(在您的 controller 下方,在 initState 内部):
      animation = ColorTween(
        begin: Colors.red,
        end: Colors.blue,
      ).animate(controller);
      

    【讨论】:

      猜你喜欢
      • 2019-09-28
      • 1970-01-01
      • 2019-07-04
      • 2021-07-19
      • 2020-08-25
      • 1970-01-01
      • 1970-01-01
      • 2021-08-27
      • 1970-01-01
      相关资源
      最近更新 更多