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

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

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

0 ответов

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

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

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

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

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

  1. В controllerбудет по-прежнему активен, даже если вы позже смените экраны. Поэтому, если у вас есть зацикленная анимация в фоновом режиме, рекомендуется избавиться от нее при смене экрана, чтобы больше не тратить на нее ресурсы телефона. Этого можно добиться с помощью:
    @override
    void dispose() {
      controller.dispose();
      super.dispose();
    }
    
  2. Вы также можете настроить, как запускается анимация или как она выполняется. Один из вариантов - использоватьCurvedAnimation.
    1. Объявить Animation animation; прямо под твоим controller.
    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);
    
Другие вопросы по тегам