[Перевод] Все, что вам нужно знать о переходе с Flutter страницы

Будущих учащихся на курсе «Flutter Mobile Developer» и всех интересующихся приглашаем записаться на открытый онлайн-урок по теме «Графика во Flutter». На уроке участники вместе с экспертом-ведущим разберут, как устроен рендеринг во Flutter и изучат основные компоненты библиотеки dart:ui.

А сейчас делимся с вами традиционным переводом интересного материала.


Мы знаем, как легко перемещаться с одного маршрута на другой в Flutter. Нам просто нужно добавить и вытащить.

Добавить:

Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => SecondRoute()),
  );

Вытащить:

Navigator.pop(context);

Вот так. Но это скучновато, нет никакой анимации на сайте

В Winkl, когда мы начали играть с анимацией, мы поняли, что переход на страницу может действительно сделать ваш пользовательский интерфейс красивым. Если вы хотите иметь слайд-переход, как IOS вы используете CupertinoPageRoute. Вот и все, ничего больше.

Но для пользовательского перехода Flutter предоставляет различные виджеты перехода. Давайте посмотрим, как мы можем их использовать.

Мы знаем, что Navigator.push принимает два аргумента (BuildContext context, Route<T> route). Мы можем создать свой собственный маршрут страницы с некоторой анимацией перехода. Давайте начнем с чего-нибудь простого, вроде слайд-перехода.

Слайд-переход

Мы расширим PageRouteBuilder и определим transitionBuilder, который вернет виджет SlideTransition. Виджет SlideTransition занимает позицию типа Animation<Offset>. Мы будем использовать Tween<Offset> для задания начального и конечного смещения.

import 'package:flutter/material.dart';
class SlideRightRoute extends PageRouteBuilder {
  final Widget page;
  SlideRightRoute({this.page})
      : super(
          pageBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
          ) =>
              page,
          transitionsBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
            Widget child,
          ) =>
              SlideTransition(
                position: Tween<Offset>(
                  begin: const Offset(-1, 0),
                  end: Offset.zero,
                ).animate(animation),
                child: child,
              ),
        );
}

Теперь мы можем использовать SlideRightRoute вместо MaterialPageRoute вот так.

Navigator.push(context, SlideRightRoute(page: Screen2()))

Результат:

Довольно просто, не так ли? Вы можете изменить направление слайд-перехода, изменив смещение.

Переход масштаба

Переход масштаба анимирует масштаб преобразованного виджета. Вы также можете изменить способ анимации, изменив кривые CurvedAnimation. В приведенном ниже примере я использовал Curves.fastOutSlowIn.

import 'package:flutter/material.dart';
class ScaleRoute extends PageRouteBuilder {
  final Widget page;
  ScaleRoute({this.page})
      : super(
          pageBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
          ) =>
              page,
          transitionsBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
            Widget child,
          ) =>
              ScaleTransition(
                scale: Tween<double>(
                  begin: 0.0,
                  end: 1.0,
                ).animate(
                  CurvedAnimation(
                    parent: animation,
                    curve: Curves.fastOutSlowIn,
                  ),
                ),
                child: child,
              ),
        );
}

Результат:

Ротационный переход

Ротационный переход анимирует ротацию виджета. Вы также можете предоставить transitionDuration для вашего PageRouteBuilder.

import 'package:flutter/material.dart';
class RotationRoute extends PageRouteBuilder {
  final Widget page;
  RotationRoute({this.page})
      : super(
          pageBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
          ) =>
              page,
          transitionDuration: Duration(seconds: 1),
          transitionsBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
            Widget child,
          ) =>
              RotationTransition(
                turns: Tween<double>(
                  begin: 0.0,
                  end: 1.0,
                ).animate(
                  CurvedAnimation(
                    parent: animation,
                    curve: Curves.linear,
                  ),
                ),
                child: child,
              ),
        );
}

Результат:

Размерный переход

Подробнее

import 'package:flutter/material.dart';
class SizeRoute extends PageRouteBuilder {
  final Widget page;
  SizeRoute({this.page})
      : super(
          pageBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
          ) =>
              page,
          transitionsBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
            Widget child,
          ) =>
              Align(
                child: SizeTransition(
                  sizeFactor: animation,
                  child: child,
                ),
              ),
        );
}

Результат:

Теневой переход

Подробнее

import 'package:flutter/material.dart';
class FadeRoute extends PageRouteBuilder {
  final Widget page;
  FadeRoute({this.page})
      : super(
          pageBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
          ) =>
              page,
          transitionsBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
            Widget child,
          ) =>
              FadeTransition(
                opacity: animation,
                child: child,
              ),
        );
}

Результат:

Здорово! Мы увидели все основные переходы.

Теперь давайте сделаем что-нибудь более продвинутое. Что если мы хотим анимировать оба маршрута. Маршрут входа (новая страница) и маршрут выхода (старая страница). Мы можем использовать анимацию перехода в стек и применить ее к обоим маршрутам. Одним из примеров может быть слайд в новом маршруте и слайд из старого маршрута. Это моя любимая анимация перехода. Давайте посмотрим, как это сделать.

import 'package:flutter/material.dart';
class EnterExitRoute extends PageRouteBuilder {
  final Widget enterPage;
  final Widget exitPage;
  EnterExitRoute({this.exitPage, this.enterPage})
      : super(
          pageBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
          ) =>
              enterPage,
          transitionsBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
            Widget child,
          ) =>
              Stack(
                children: <Widget>[
                  SlideTransition(
                    position: new Tween<Offset>(
                      begin: const Offset(0.0, 0.0),
                      end: const Offset(-1.0, 0.0),
                    ).animate(animation),
                    child: exitPage,
                  ),
                  SlideTransition(
                    position: new Tween<Offset>(
                      begin: const Offset(1.0, 0.0),
                      end: Offset.zero,
                    ).animate(animation),
                    child: enterPage,
                  )
                ],
              ),
        );
}

И используйте его вот так.

Navigator.push(context,
    EnterExitRoute(exitPage: this, enterPage: Screen2()))

Результат:

Мы также можем объединить несколько переходов, чтобы создать нечто удивительное, например, масштаб и ротацию одновременно. Во-первых, есть ScaleTransition, его дочерним элементом является RotationTransition, а его дочерним элементом — страница.

import 'package:flutter/material.dart';
class ScaleRotateRoute extends PageRouteBuilder {
  final Widget page;
  ScaleRotateRoute({this.page})
      : super(
          pageBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
          ) =>
              page,
          transitionDuration: Duration(seconds: 1),
          transitionsBuilder: (
            BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
            Widget child,
          ) =>
              ScaleTransition(
                scale: Tween<double>(
                  begin: 0.0,
                  end: 1.0,
                ).animate(
                  CurvedAnimation(
                    parent: animation,
                    curve: Curves.fastOutSlowIn,
                  ),
                ),
                child: RotationTransition(
                  turns: Tween<double>(
                    begin: 0.0,
                    end: 1.0,
                  ).animate(
                    CurvedAnimation(
                      parent: animation,
                      curve: Curves.linear,
                    ),
                  ),
                  child: child,
                ),
              ),
        );
}

Результат:

Отличная работа, ребята! Это все, что вам нужно знать об анимации перехода по маршруту в Flutter. Попробуйте совместить какой-нибудь переход и сделать что-нибудь замечательное. Если вы сделаете что-то интересное, вы можете поделиться этим со мной. Весь исходный код здесь на GitHub repo. Связаться со мной можно в Twitter, Github и LinkedIn.


Узнать подробнее о курсе «Flutter Mobile Developer».

Записаться на открытый онлайн-урок по теме «Графика во Flutter».


ЗАБРАТЬ СКИДКУ

Let’s block ads! (Why?)

Read More

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *