Flutter loader: resize and rotate at the same time

Viewed 525

I'm new to Flutter and would like to make a customized loader, but can't find a solution. When a user clicks on a button and some operation begins, I'd like to show a customized widget (basically a loader, notifying a user that operation has begun) that pops up to the center of the screen and grows in size (from 0x0 to 300x300), while it is rotating at the same time. When it reaches maximum size (300x300), I want it to shrink back to the size of 0x0 and hide/disappear, while rotating as well. This animation should take 2 seconds. If after 2 seconds the operation is not completed, I'd like to start over with the animation.

1 Answers

You can create your own animations very easily. Using Animation and AnimationController you can do basically anything that you can think of.

Check out this video if you want to dig deeper into Animations with Flutter to make Complex UIs

To achieve what you are asking, you can build your Loading Indicator using a stateless widget.

Here is an interactive example

class MyLoadingIndicator extends StatefulWidget {
  final Widget child;
  const MyLoadingIndicator({
    @required this.child,
    Key key,
  }) : super(key: key);

  @override
  _MyLoadingIndicatorState createState() => _MyLoadingIndicatorState();
}

class _MyLoadingIndicatorState extends State<MyLoadingIndicator> with TickerProviderStateMixin {
  AnimationController rotateController;
  Animation<double> rotateAnimation;
  AnimationController scaleController;
  Animation<double> scaleAnimation;

  @override
  void initState() {
    super.initState();
    rotateController = AnimationController(
      duration: const Duration(seconds: 1),
      reverseDuration: const Duration(seconds: 1),
      vsync: this,
    );

    rotateAnimation = CurvedAnimation(parent: rotateController, curve: Curves.linear);
    rotateController.repeat(
      min: 0,
      max: 1,
      period: Duration(seconds: 2),
    );
    scaleController = AnimationController(
      duration: const Duration(seconds: 1),
      reverseDuration: const Duration(seconds: 1),
      vsync: this,
    );

    scaleAnimation = CurvedAnimation(parent: scaleController, curve: Curves.linear);
    scaleController.repeat(
      min: 0,
      max: 1,
      period: Duration(seconds: 2),
      reverse: true,
    );
  }

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

  @override
  Widget build(BuildContext context) {
    return RotationTransition(
      turns: rotateAnimation,
      child: ScaleTransition(
        scale: scaleAnimation,
        child: Container(
          height: 300,
          width: 300,
          color: Colors.red,
          child: widget.child,
        ),
      ),
    );
  }
}
Related