Будущих учащихся на курсе «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».

ссылка на оригинал статьи https://habr.com/ru/company/otus/blog/539190/
Добавить комментарий