Как изменить скорость анимации героя во флаттере

Я сделал простую анимацию героя, следуя инструкциям с веб-сайта Flutter

Он работает, как описано в инструкциях, но в моем случае я бы хотел, чтобы он анимировался намного медленнее с первого экрана на второй. кто-нибудь знает как изменить скорость этой анимации?


person Asger Lorenzen    schedule 11.12.2018    source источник
comment
это зависит от продолжительности перехода PageRoute, поэтому вам нужно будет создать / реализовать свой собственный PageRoute   -  person diegoveloper    schedule 11.12.2018
comment
вы можете найти это решение полезным здесь   -  person Hazem Ashraf    schedule 19.02.2019


Ответы (2)


Чтобы изменить скорость перехода, вам необходимо настроить переход 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,
          ),
        ),
      ),
    );
  }
}
person NiklasPor    schedule 21.03.2019

1. Возможное решение

Я не думаю, что единственный способ добиться этого - изменить продолжительность перехода PageRoute. Я думаю, что вы также можете добиться того же эффекта, используя AnimationController - этот ответ в основном взят из лекций № 149 и № 150 из Полный учебный курс Анджелы Ю по разработке Flutter 2019 с Dart.

  1. Превратите свой экран в StatefulWidget.
  2. Если вы используете только одну анимацию, добавьте with SingleTickerProviderStateMixin в свой класс состояния.
  3. Создайте контроллер внутри класса состояния.
  4. If your animation is supposed to appear on the initialization of the screen, use the controller inside the initState method.
    • The controller has a property called duration, so you can change it to your liking.

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) параметр, который принимает сам объект состояния (экземпляра) (обычно).
  • addListener и setState доступны, если вы хотите использовать значение controller (controller.value) в какой-то момент в будущем - например, изменив высоту значка на что-то вроде height: finalHeight * controller.value.
  • Для перехода к этому экрану я просто использую FlatButton с Navigator.pushNamed, ничего особенного.

3. Дополнительная важная информация

  1. The controller will still be active even if you change screens later. So if you have a looping animation in the background, it's a good idea to dispose it when changing the screen, this way you don't waste phone resources with it anymore. This could be achieved with:
    @override
    void dispose() {
      controller.dispose();
      super.dispose();
    }
    
  2. You could also customize how the animation is run, or how it is executed. One option is to use a CurvedAnimation.
    1. Declare Animation animation; right below your controller.
    2. Below your controller, inside initState, add:
      animation = CurvedAnimation( // the controller can't have upperBound > 1
        parent: controller,        // the controller you created
        curve: Curves.decelerate,
      );
      
  3. Another useful way of animating in Flutter is by using TweenAnimations. For example, if you want to transition between colors, you could use ColorTween (below your controller, inside initState):
    animation = ColorTween(
      begin: Colors.red,
      end: Colors.blue,
    ).animate(controller);
    
person Philippe Fanaro    schedule 06.11.2019