Flutter: Creating an add_close AnimatedIcons

Viewed 3733

I'd like to create a beginning icon as Icon.add and end icon which is Icon.close in the AnimatedIcon widget. For e.g. their is a prebuilt animation of add_event that corresponds to begin animation = add and end animation = event. I'd like to change the end animation to be Icon.close. It's unclear how to do this as there's no documentation readily available for creating custom animations. The most relevant code I could find is: https://github.com/flutter/flutter/blob/e10df3c1a65f9d7db3fc5340cffef966f7bd40a6/packages/flutter/lib/src/material/animated_icons/data/add_event.g.dart. I believe I should use vitool. How can I go about creating new animations?

3 Answers

So I had some free time and this is something many people might want to use at some point as we do not have much options for AnimatedIcons that are already given to us. So I went ahead and built this small package and uploaded it on pub dart that solves what you are looking for. With this package you can animate any two icons.

Check on pub dart animate_icons

Simply add the package into pubspec.yaml like this:

animate_icons:

Then use this Widget like this:

AnimateIcons(
    startIcon: Icons.add,
    endIcon: Icons.close,
    size: 60.0,
    onStartIconPress: () {
        print("Clicked on Add Icon");
    },
    onEndIconPress: () {
        print("Clicked on Close Icon");
    },
    duration: Duration(milliseconds: 500),
    color: Theme.of(context).primaryColor,
    clockwise: false,
),

Yes, friend, you need to create your own animation

I have written code for the situation that you talked about

I used to Transform widget , and AnimationController

import 'dart:math';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
  AnimationController animatedController;
  double _angle = 0;

  @override
  void initState() {
    animatedController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 300));
    animatedController.addListener(() {
      setState(() {
        _angle = animatedController.value * 45 / 360 * pi * 2;
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            body: Center(
      child: InkResponse(
        onTap: () {
          if (animatedController.status == AnimationStatus.completed)
            animatedController.reverse();
          else if (animatedController.status == AnimationStatus.dismissed)
            animatedController.forward();
        },
        child: Transform.rotate(
          angle: _angle,
          child: Icon(
            Icons.add,
            size: 50,
          ),
        ),
      ),
    )));
  }
}

If you need to customize more than this, Take a look at the AnimatedContainer

if the simple transition between the two icons is enough, then simple_animated_icon package might be useful.

class AnimatedIconButton extends StatefulWidget {
  @override
  _AnimatedIconButtonState createState() => _AnimatedIconButtonState();
}

class _AnimatedIconButtonState extends State<AnimatedIconButton>
    with SingleTickerProviderStateMixin {
  bool _isOpened = false;
  AnimationController _animationController;
  Animation<double> _progress;

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

    _animationController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 300))
          ..addListener(() {
            setState(() {});
          });

    _progress =
        Tween<double>(begin: 0.0, end: 1.0).animate(_animationController);
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  void animate() {
    if (_isOpened) {
      _animationController.reverse();
    } else {
      _animationController.forward();
    }

    setState(() {
      _isOpened = !_isOpened;
    });
  }

  @override
  Widget build(BuildContext context) {
    return IconButton(
        onPressed: animate,
        icon: SimpleAnimatedIcon(
          startIcon: Icons.add,
          endIcon: Icons.close,
          progress: _progress,
        ));
  }
}
Related