Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter Custom Animated Icon

Tags:

flutter

dart

I am looking to make a item that gets added and removed from list.

what I am looking for is to have the + icon and the - icon and animate between the 2 for a clean and smooth look.

I have the following code

Container(
            padding: EdgeInsets.fromLTRB(0, 0, 20, 0),
            child: AnimatedIcon(
              icon: AnimatedIcons.home_menu,
              progress: _animationController,
              color: Colors.white,
            ))

with

void _handleOnPressed() {
setState(() {
  isPlaying = !isPlaying;
  isPlaying
      ? _animationController.forward()
      : _animationController.reverse();
  });
}

This for fine for the built in animated icons in flutter.

I am looking to use the + and the - icon, but with the same look.

Is there a way to do this?

like image 444
Bnd10706 Avatar asked Nov 15 '19 18:11

Bnd10706


People also ask

How do you animate a widget in flutter?

The animations are considered hard work and take time to learn. Flutter made it easy with its packages. To animate the widgets without much effort, we can wrap them inside different defined animated widgets in the animate_do package.


3 Answers

You're in luck my friend! Flutter already has you covered with AnimatedIcon()

AnimatedIcon Class in the docs

Animated Icon Widget of the week Video

Now to animate your Icons with Flare. Jeff Delaney made a good tutorial for this.

https://fireship.io/lessons/animated-navigation-flutter-flare/

like image 109
Patrick Kelly Avatar answered Sep 22 '22 05:09

Patrick Kelly


I know it's not as beautiful as AnimatedIcon, but you could actually get very similar transition with any 2 icons of your choice with just a few lines of code:

 IconButton(
      icon: AnimatedSwitcher(
          duration: const Duration(milliseconds: 300),
          transitionBuilder: (child, anim) => RotationTransition(
                turns: child.key == ValueKey('icon1')
                    ? Tween<double>(begin: 1, end: 0.75).animate(anim)
                    : Tween<double>(begin: 0.75, end: 1).animate(anim),
                child: FadeTransition(opacity: anim, child: child),
              ),
          child: _currIndex == 0
              ? Icon(Icons.close, key: const ValueKey('icon1'))
              : Icon(
                  Icons.arrow_back,
                  key: const ValueKey('icon2'),
                )),
      onPressed: () {
        setState(() {
          _currIndex = _currIndex == 0 ? 1 : 0;
        });
      },
    );

Result: result


Or you can use ScaleTransition instead of FadeTransition, and get even more similar animation:

IconButton(
      icon: AnimatedSwitcher(
          duration: const Duration(milliseconds: 350),
          transitionBuilder: (child, anim) => RotationTransition(
                turns: child.key == ValueKey('icon1')
                    ? Tween<double>(begin: 1, end: 0.75).animate(anim)
                    : Tween<double>(begin: 0.75, end: 1).animate(anim),
                child: ScaleTransition(scale: anim, child: child),
              ),
          child: _currIndex == 0
              ? Icon(Icons.close, key: const ValueKey('icon1'))
              : Icon(
                  Icons.arrow_back,
                  key: const ValueKey('icon2'),
                )),
      onPressed: () {
        setState(() {
          _currIndex = _currIndex == 0 ? 1 : 0;
        });
      },
    )

Result: result-2


With this approach you could use any icons you want, and it doesn't require creating separate AnimationController just to control the transition, unlike AnimatedIcon

like image 24
emvaized Avatar answered Sep 18 '22 05:09

emvaized


Flutter is providing AnimatedIcon can be use, This is an example how to use it.

class _CreatePackageViewState extends State<CreatePackageView>
    with SingleTickerProviderStateMixin {  
       bool expanded = true;
       late AnimationController controller;
      @override
       void initState() {
        super.initState();
        controller = AnimationController(
          vsync: this,
          duration: Duration(milliseconds: 400),
          reverseDuration: Duration(milliseconds: 400),
        );
      }



      IconButton(
            icon: AnimatedIcon(
              icon: AnimatedIcons.menu_close,
              progress: controller,
              semanticLabel: 'Show menu',
            ),
            onPressed: () {
              setState(() {
                expanded ? controller.forward() : controller.reverse();
                expanded = !expanded;
              });
            }),

    }

like image 30
Juan Manuel Mayobre Avatar answered Sep 21 '22 05:09

Juan Manuel Mayobre