Как реализовать анимацию флаттера
Как создать анимацию для перемещения изображения из центра в верхнюю часть экрана? Клиент спросил, что заставка имеет значок в центре экрана и что при отображении экрана входа значок будет перемещен в верхнюю часть экрана и отобразятся поля для входа. Кто-нибудь может мне помочь?
1 ответ
Это кажется идеальным кандидатом для использования анимации героя, так как большая часть работы уже сделана для вас. Хотя я должен отметить несколько вещей.
Заставка, которая отображается при запуске приложения на Android и iOS, определяется непосредственно в iOS и Android и должна быть статической.
Невозможно определить этот экран-заставку с помощью флаттера.
Вместо этого я бы порекомендовал указать простой экран-заставку в iOS и Android напрямую. Затем создайте страницу во флаттере, которая выглядит идентично этому экрану. Таким образом, вы можете пойти из
родная заставка
->
заставка флаттера----animate--->
экран входа.
Я создал быстрый макет того, как это может выглядеть.
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: SplashPage(),
);
}
}
enum SplashHeroes { icon }
class SplashPage extends StatefulWidget {
@override
SplashPageState createState() {
return new SplashPageState();
}
}
class SplashPageState extends State<SplashPage> {
@override
void initState() {
super.initState();
Future.delayed(Duration(seconds: 1), _toNext);
}
_toNext() {
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, _, __) => LoginPage(),
transitionsBuilder: (context, animation, secondaryAnimation, child) => FadeTransition(
opacity: animation,
child: child,
),
),
);
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.blue,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Hero(
tag: SplashHeroes.icon,
createRectTween: (rect1, rect2) => RectTween(begin: rect1, end: rect2),
child: Icon(
Icons.airport_shuttle,
size: 100.0,
color: Colors.white,
),
),
FlatButton(
child: Text("Next"),
onPressed: _toNext,
),
],
),
);
}
}
class LoginPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: <Widget>[
Hero(
createRectTween: (rect1, rect2) => RectTween(begin: rect1, end: rect2),
tag: SplashHeroes.icon,
child: Icon(
Icons.airport_shuttle,
color: Colors.white,
),
),
],
),
backgroundColor: Colors.deepPurple,
body: Center(
child: Column(
children: <Widget>[
Text("Username"),
TextField(),
Text("Password"),
TextField(),
],
),
),
);
}
}
В этом коде нужно отметить несколько вещей.
Он использует PageRouteBuilder, который выполняет только базовую работу по переходу на затухание. Вы можете добавить к этому или сделать свое собственное переопределение PageRoute. Я также предположил, что вам нужен переход с постепенным исчезновением, а не обычный переход материала, поскольку он имеет тенденцию выглядеть лучше для заставки -> переход первого экрана.
В
debug
В режиме, когда вы делаете анимацию в первый раз, она фактически пропускает кадры, которые вы хотите анимировать. Либо выполните сборку в режиме разблокировки, либо дождитесь автоматического перехода, нажмите "Назад", затем нажмите "Далее".Я добавил
createRectTween
так что анимация идет прямо из центра в угол. Если вы не определили это, вместо этого используется изогнутый маршрут. Твой выбор.Значки имеют заданный размер, и я не стал ничего переопределять, чтобы сделать так, чтобы размер анимировался от угла к середине. Если вы используете картинку, я думаю, что размер тоже оживит, хотя я не уверен на 100% в этом.
Я просто поместил значок в "действия" панели приложения в качестве примера. Вы можете поместить значок в любое место (и даже не использовать панель приложений, если не хотите) - переход героя будет работать везде, где вы поместите значок.
enum SplashHeroes
важно, потому что флаттеру нужен способ подойти к различным героям. В этом случае есть только один, но теоретически вы можете иметь несколько из них с собственными типами переходов. Использование enum говорит флаттеру, что герой содержит тот же виджет (или, по крайней мере, виджет, на который вы хотите перейти в / из).
Обратите внимание, что я на самом деле не отвечал на ваш вопрос напрямую ("как реализовать анимацию трепетания", а скорее в том, что вы объяснили, в чем заключалась ваша проблема), поэтому, если это поможет, я поменяю название на что-то более подходящее, чтобы кто-то другой не стал наткнуться на него, глядя, как настроить общую анимацию флаттера.