Flutter

Entendendo animações explícitas e implícitas

Rafael Almeida Barbosa

Android/Flutter Developer - CEO Boleiro

I

Animação

  • Claymation
  • Stop Motion

1 - 35

2 - 35

Animação

  • Movimento phi

Max Wertheimer 

1912

3 - 35

Animações

Porque utiliza-las?

Issara Willenskomer

Felippe Silveira

4 - 35

Animações em Flutter

Explícitas

Implícitas

5 - 35

Animações Explícitas

  • Animation
  • AnimationController
  • Tween
  • Transition
  • AnimatedBuilder

6 - 35

Animation

  • value
  • status: forward
  • status: reverse
  • status: completed
  • status: dismissed

7 - 35

AnimationController



        _controller = AnimationController(
          vsync: this, // the SingleTickerProviderStateMixin
          duration: Duration(seconds: 2),
        );

        _controller.forward();
        _controller.reverse();

8 - 35

Tween





        _animation = Tween<Offset>(
          begin: const Offset(100.0, 50.0),
          end: const Offset(200.0, 300.0),
        ).animate(_controller);

9 - 35

Transition

(AnimatedWidget)

  • SlideTransition
  • ScaleTransition
  • RotationTransition
  • SizeTransition
  • FadeTransition
  • PositionedTransition
  • RelativePositionedTransition
  • DecoratedBoxTransition
  • AlignTransition
  • DefaultTextStyleTransition

10 - 35

FadeTransition

  @override
  void initState() {
    super.initState();

    _controller =
        AnimationController(vsync: this, duration: Duration(seconds: 2));

    _controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FadeTransition(
          opacity: _controller,
          child: Center(
            child: Container(
              width: 100.0,
              height: 100.0,
              color: Colors.blue,
            )
        ),
      ),
    );
  }

11 - 35

FadeTransition

12 - 35

ScaleTransition

  @override
  void initState() {
    super.initState();

    _controller =
        AnimationController(vsync: this, duration: Duration(seconds: 2));

    _controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ScaleTransition(
          scale: _controller,
          child: Center(
            child: Container(
              width: 100.0,
              height: 100.0,
              color: Colors.blue,
            )
        ),
      ),
    );
  }

13 - 35

ScaleTransition

14 - 35

RotationTransition

  @override
  void initState() {
    super.initState();

    _controller =
        AnimationController(vsync: this, duration: Duration(seconds: 2));

    _controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: RotationTransition(
          turns: _controller,
          child: Center(
            child: Container(
              width: 100.0,
              height: 100.0,
              color: Colors.blue,
            )
        ),
      ),
    );
  }

15 - 35

RotationTransition

16 - 35

Fade and Scale


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FadeTransition(
        opacity: _controller,
        child: ScaleTransition(
            scale: _controller,
            child: Center(
              child: InkWell(
                onTap: (){
                  _controller.forward(from: 0.0);
                },
                child: Container(
                  width: 100.0,
                  height: 100.0,
                  color: Colors.blue,
                ),
              )
          ),
        ),
      ),
    );
  }

17 - 35

Fade and Scale

18 - 35

AnimatedBuilder

  
    _animation = Tween(begin: -1.0, end: 0.0).animate(CurvedAnimation(
      parent: _controller,
      curve: Curves.fastOutSlowIn,
    ));
    ....

    final double width = MediaQuery.of(context).size.width;
    return Scaffold(
      body: AnimatedBuilder(
          animation: _controller,
          builder: (BuildContext context, Widget child) {
            return Transform(
              transform:
              Matrix4.translationValues(_animation.value * width, 0.0, 0.0),
              child: child,
            );
          },
          child: new Center(
            child: Container(
              width: 100.0,
              height: 100.0,
              color: Colors.blue,
            )
          ),
      ),
    );

19 - 35

AnimatedBuilder

20 - 35

Animações Implícitas

(ImplicitlyAnimatedWidget)

  • AnimatedContainer
  • AnimatedPadding
  • AnimatedAlign
  • AnimatedPositioned
  • AnimatedPositionedDirectional
  • AnimatedOpacity
  • AnimatedDefaultTextStyle
  • AnimatedPhysicalModel
  • Hero

21 - 35

AnimatedPadding

 
 double paddingVertical = 20.0;
 double paddingHorizontal = 50.0;
 
 @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: AnimatedPadding(
        duration: Duration(seconds: 1),
          padding: EdgeInsets.only(right: paddingHorizontal,left: paddingHorizontal,
              top: paddingVertical,bottom: paddingVertical),
          child: InkWell(
            onTap: (){
              setState(() {
                 paddingVertical = 200.0;
                 paddingHorizontal = 20.0;
              });
            },
            child: Container(
              color: Colors.blue,
            ),
          ),
      ),
    );
  }

22 - 35

AnimatedPadding

23 - 35

AnimatedContainer

  double paddingVertical = 20.0;
  double paddingHorizontal = 50.0;
  Color color = Colors.blue;
  double axisX = -100;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: AnimatedContainer(
          duration: Duration(seconds: 1),
          color: color,
          padding: EdgeInsets.only(right: paddingHorizontal,left: paddingHorizontal,
              top: paddingVertical,bottom: paddingVertical),
            transform: Matrix4.translationValues(axisX, 0.0, 0.0),
            child: InkWell(
              onTap: (){
                setState(() {
                  color = Colors.red;
                  paddingVertical = 80.0;
                  paddingHorizontal = 20.0;
                  axisX = 0.0;
                });
              },
              child: Container(
                width: 100,
                height: 100,
              ),
            ),
        ),
      ),
    );
  }

24 - 35

AnimatedContainer

24 - 35

Hero

  
  Widget build(BuildContext context) {
    return SizedBox(
      width: width,
      child: Hero(
        tag: photo,
        child: Material(
          color: Colors.transparent,
          child: InkWell(
            onTap: onTap,
            child: Image.asset(
              photo,
              fit: BoxFit.contain,
            ),
          ),
        ),
      ),
    );
  }

24 - 35

Hero

24 - 35

Dicas/ Boas práticas

  • warn: Animação de opacidade

 

  • Não utilize setState() no listener do Animation

24 - 35

UseCase

24 - 35

UseCase

24 - 35

Referencias

  • Animação. Disponível em: <https://pt.wikipedia.org/wiki/Anima%C3%A7%C3%A3o> Acesso em: 1 de abril de 2019

 

  • Animations in Flutter. Disponível em: <https://proandroiddev.com/animations-in-flutter-6e02ee91a0b2/> Acesso em: 1 de abril de 2019

 

  • Implicitly Animated Widgets in Flutter. Disponível em: <https://medium.com/flutter-community/animated-widgets-in-flutter-763fd5dd6d01/> Acesso em: 1 de abril de 2019

 

  • Animations tutorial. Disponível em: <https://flutter.dev/docs/development/ui/animations/tutorial/> Acesso em: 1 de abril de 2019

Obrigado!

GithubPage: http://rafaelbarbosatec.github.io

LInkedln: https://www.linkedin.com/in/rafael-almeida-7667a063

Medium: @rafaelbarbosatec

Made with Slides.com