Flutter - Incluindo animação na sua aplicação - I


Nesta série de artigos vamos mostrar como podemos adicionar animação na nas aplicações Flutter.

O que é o Flutter ?

O Flutter é um SDK de aplicativo móvel do Google que ajuda a criar aplicativos móveis modernos para iOS e Android usando uma única (quase) base de código.

Se você não conhece o Flutter veja o meu artigo :  Flutter - Primeiros contatos e impressões

Animação no Flutter

Atualmente, as animações em uma interface de usuário são um grande negócio. Os usuários esperam que seus aplicativos movam-se visualmente e que façam isso de forma visualmente atraente. O Flutter fornece alguns
widgets de animação para esse fim que iremos abordar.

Assim, o objetivo de adicionar animação em uma aplicação Flutter é melhorar a experiência do usuário (UX).

O Flutter possui dois tipos de animação:

  1. Baseada em física - É usada para imitar o comportamento do mundo real;
     
  2. Tween - É uma abreviação para 'in-Between' oque significa que a animação terá pontos de início e de término, uma linha do tempo, e uma curva que especifica o tempo e a velocidade da transição; (Neste caso o framework calcula automaticamente a transição do ponto inicial ao ponto final)

A biblioteca de animação fornece uma variedade de funções para implementar várias animações em aplicativos Flutter. Alguns dos membros interessantes incluem :

Animation - Esta classe contém informações básicas sobre um animação, coisas como se está funcionando e permitindo que você conecte o ouvinte de eventos funciona para ele.

AnimationController - Esta classe permite controlar um animação, coisas como iniciar e parar, redefinir e repetir uma animação;

Curve - Esta classe contém dados que definem uma curva de flexibilização, o que permite que você tenha animações que não são estritamente lineares na aparência. Existem inúmeras subclasses de Curve, incluindo Cubic, ElasticInOutCurve, Interval e SawTooth que definem flexibilizações comuns;

Tween - Como Curve, esta classe contém dados que definem uma determinado tipo de operação de interpolação e, como o Curve, possui muitas subclasses para interpolações comuns como ColorTween (interpolação entre duas cores)

TextStyleTween (para animar entre dois estilos de texto, como do texto normal para o negrito) e RectTween (interpolação entre dois retângulos, talvez para animar o tamanho de um retângulo)

Vamos começar com uma animação bem simples.

Recursos usados:

Usando o widget AnimatedContainer

O widget AnimatedContainer é uma versão animada do Container.

Para animações relativamente simples, o widget AnimatedContainer é perfeito. Ele muda gradualmente seus valores durante um período definido de tempo.

Isso é feito automaticamente - basta dizer quais são os valores iniciais e depois mudar para os novos valores e ele será animado (ou interpolado) conforme necessário. Propriedades nulas não são animadas e os filhos e descendentes deste widget também não são animados.

O construtor AnimatedContainer possui argumentos chamados : duration, curve, color, height, width, child, decoration, transform dentre outros.

A primeira coisa a fazer é criar um projeto Flutter chamado flut_anima1:

No Visual Studio Code tecle CTRL+ SHIFT+P para abrir a paleta de comandos e a seguir selecione a opção : Fluter:New Project;

A seguir informe o nome do projeto : flut_anima1 e tecle ENTER;

Na janela de diálogo a seguir selecione uma pasta local onde o projeto vai ser salvo e clique em : Select a folder to create the project in;

O Flutter vai criar um projeto padrão onde todo o código da aplicação vai estar no arquivo main.dart dentro da pasta lib do projeto;
 

Vamos alterar o código do arquivo main.dart na pasta lib que foi gerado durante a criação do projeto conforme abaixo:

import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
        title: 'Animação',
        theme: ThemeData(
        primarySwatch: Colors.blue,
    ),
    home: Home(),
    );
  }
}

A classe MyApp retorna um widget MaterialApp que declara propriedades de título, tema e página inicial. Observe que a propriedade home chama a classe Home() que iremos criar a seguir na pasta lib do projeto.

Na pasta lib do projeto vamos criar o arquivo home.dart e a seguir inicie digitando stf no arquivo e a seguir selecionar a opção : Flutter stateful widget

Será criado o código padrão do StatefulWidget, basta você digitar o nome do widget: Home.

Teremos o código abaixo:

import 'package:flutter/material.dart';
class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
  @override
  Widget build(BuildContext context) {
   return Scaffold(
        appBar: AppBar(
          title: Text('Home'),
      ),
      body: Container(),
    );
  }
}

Estamos usando um StatefulWidget para a classe Home porque para nossa aplicação vamos manter Estado dos dados usados na aplicação. Estado é a informação que pode ser lida de forma síncrona quando o widget é construído e que pode mudar durante o tempo de vida do widget.

Aqui estamos usando o widget Scaffold que implementa o layout visual básico do Material Design, permitindo a adição de AppBar, BottomAppBar, FloatingActionButton, Drawer, SnackBar, BottomSheet e outros recursos.

Até aqui criamos a estrutura básica do projeto onde iremos a seguir mostrar como realizar animações usandos os widgets do Flutter.

Criando a animação com AnimatedContainer

Vamos criar agora o arquivo animated_container.dart na pasta lib do projeto. Começe digitanto stf no arquivo e selecione a opção Flutter stateful widget

A seguir informe o nome AnimatedContainerWidget e importe o pacote flutter/material.dart no projeto:

import 'package:flutter/material.dart';
class AnimatedContainerWidget extends StatefulWidget {
  @override
  _AnimatedContainerWidgetState createState() => _AnimatedContainerWidgetState();
}
class _AnimatedContainerWidgetState extends State<AnimatedContainerWidget> {
  @override
  Widget build(BuildContext context) {
    return Container(
    );
  }
}

Vamos incluir as variáveis para _altura e _largura como sendo do tipo double e também definir o método _aumentaLargura() que vai chamar o método setState() para notificar o framework que o valor da largura foi alterado e agendar a sua reconstrução para o estado deste objeto redesenhar a sua sub-árvore.

...
class _AnimatedContainerWidgetState extends State<AnimatedContainerWidget> {
  double _altura = 100.0;
  double _largura = 100.0;

  _aumentaLargura() {
      setState(() {
      _largura = _largura >= 320.0 ? 100.0 : _largura += 50.0;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(     
    );
  }
}

A seguir vamos concluir a definição do código da classe Home definindo uma linha (Row) tendo como filho um widget AnimatedContainer onde definimos os argumentos : duration, curve, color, height e width.

Definimos um FlatButton que no evento OnPressed permite alterar a largura do container:

...
class _AnimatedContainerWidgetState extends State<AnimatedContainerWidget> {
  double _altura = 100.0;
  double _largura = 100.0;
  _aumentaLargura() {
      setState(() {
      _largura = _largura >= 320.0 ? 100.0 : _largura += 50.0;
    });
  }

 @override
 Widget build(BuildContext context) {
  return Row(
    children: <Widget>[
      AnimatedContainer(
        duration: Duration(milliseconds: 500),
        curve: Curves.elasticOut,
        color: Colors.amber,
        height: _altura,
        width: _largura,
        child: FlatButton(
          child: Text('Toque para\nAumentar a Largura\n$_largura'),
            onPressed: () {
              _aumentaLargura();
            },
          ),
        ),
      ],
    );
  }
}

Quando a página for carregada, as variáveis _altura e _largura serão iniciadas com valores de 100.0 pixels.

Quando o FlatButton for tocado, a propriedade onPressed vai chamar o método _aumentaLargura().

Nota: As variáveis e métodos definidos como sublinhado(_) inicial indicam que o seu escopo é privado.

Definimos o valor de 320,0 pixels como a largura máxima permitida, e, com cada evento de toque, aumentamos a largura atual em 50,0 pixels a partir de 100,0 pixels.

À medida que a largura aumenta, uma vez acima de 320,0 pixels, redefinimos o tamanho para 100.0 píxeis.

Para calcular a nova  _largura do AnimatedContainer, usamos o operador ternário (?) :

1 - Se a largura for maior ou igual a 320,0 pixels, definimos _largura com os 100,0 pixels originais. Isso vai
animar o AnimatedContainer de volta ao tamanho original;

2 - Caso contrário, pegamos o valor atual de _largura e adicione 50,0 pixels;

Assim, já temos tudo pronto para testar a nossa primeira animação.

Abra o arquivo home.dart e inclua o código destacado em azul abaixo :

import 'package:flut_anima1/animated_container.dart';
import 'package:flutter/material.dart';
class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
  @override
  Widget build(BuildContext context) {
   return Scaffold(
        appBar: AppBar(
          title: Text('AnimatedContainer'),
      ),
      body: SafeArea(
        child: Column(
          children: <Widget>[
            AnimatedContainerWidget(),
          ],
         )
       ),
    );
  }
}

No argumento body usamos o widget SafeArea que é um widget Padding mais poderoso.

Ao agruparmos outro widget com a SafeArea, ele adicionará qualquer preenchimento necessário para impedir que o widget seja bloqueado pela barra de status do sistema, seja recortado ou sobreposto devido ao entalhe.

A seguir definimos um widget Column que tem como filho a chamada ao nosso AnimatedContainerWidget().

Executando o projeto teremos o resultado abaixo:

Na próxima parte do artigo veremos como usar o widget AnimatedCrossFade.

"Então, aproximando-se dele um escriba, disse-lhe: Mestre, seguir-te-ei para onde quer que fores.
Mas Jesus lhe respondeu: As raposas têm seus covis, e as aves do céu, ninhos; mas o Filho do Homem não tem onde reclinar a cabeça."
Mateus 8:19,20

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Referências:


José Carlos Macoratti