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

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

1 ответ

Это кажется идеальным кандидатом для использования анимации героя, так как большая часть работы уже сделана для вас. Хотя я должен отметить несколько вещей.

  1. Заставка, которая отображается при запуске приложения на Android и iOS, определяется непосредственно в iOS и Android и должна быть статической.

  2. Невозможно определить этот экран-заставку с помощью флаттера.

Вместо этого я бы порекомендовал указать простой экран-заставку в 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(),
          ],
        ),
      ),
    );
  }
}

В этом коде нужно отметить несколько вещей.

  1. Он использует PageRouteBuilder, который выполняет только базовую работу по переходу на затухание. Вы можете добавить к этому или сделать свое собственное переопределение PageRoute. Я также предположил, что вам нужен переход с постепенным исчезновением, а не обычный переход материала, поскольку он имеет тенденцию выглядеть лучше для заставки -> переход первого экрана.

  2. В debug В режиме, когда вы делаете анимацию в первый раз, она фактически пропускает кадры, которые вы хотите анимировать. Либо выполните сборку в режиме разблокировки, либо дождитесь автоматического перехода, нажмите "Назад", затем нажмите "Далее".

  3. Я добавил createRectTween так что анимация идет прямо из центра в угол. Если вы не определили это, вместо этого используется изогнутый маршрут. Твой выбор.

  4. Значки имеют заданный размер, и я не стал ничего переопределять, чтобы сделать так, чтобы размер анимировался от угла к середине. Если вы используете картинку, я думаю, что размер тоже оживит, хотя я не уверен на 100% в этом.

  5. Я просто поместил значок в "действия" панели приложения в качестве примера. Вы можете поместить значок в любое место (и даже не использовать панель приложений, если не хотите) - переход героя будет работать везде, где вы поместите значок.

  6. enum SplashHeroes важно, потому что флаттеру нужен способ подойти к различным героям. В этом случае есть только один, но теоретически вы можете иметь несколько из них с собственными типами переходов. Использование enum говорит флаттеру, что герой содержит тот же виджет (или, по крайней мере, виджет, на который вы хотите перейти в / из).

Обратите внимание, что я на самом деле не отвечал на ваш вопрос напрямую ("как реализовать анимацию трепетания", а скорее в том, что вы объяснили, в чем заключалась ваша проблема), поэтому, если это поможет, я поменяю название на что-то более подходящее, чтобы кто-то другой не стал наткнуться на него, глядя, как настроить общую анимацию флаттера.

Другие вопросы по тегам