Introducing Motion Widget in Flutter

Sumeet Rukeja
Flutter Community
Published in
4 min readMar 11, 2020

Animations! One of the most valuable aspects of modern-day apps. Now-a-days, it’s hard to imagine an app without them. Even if we come across any such monotonous & boring-looking app, it’s difficult maintaining an interest in using it, no? Animations do take app’s UX to next level.

All front-end technologies provide a full-fledged support for animations and screen transitions. Whether it’s Google’s Material design or Apple’s Flat design, these guidelines solely concentrate on improving user-engagement in apps.

As I’m an Android developer (by day) and a Flutter enthusiast (by night) 😜, let’s concentrate on these two technologies here onwards. Android now has something called Motion Layout which works with view constraints and enables developers achieve tricky animations effortlessly. It also has LayoutAnimationController which builds beautiful, animated layouts wherein each view starts animating at a different time. These 2 features inspired me to build something similar for Flutter. I call it : Motion Widget.

What is Motion Widget?

Before we get into its details, let me show you what it’s capable of doing(with utmost ease, of course).

Motion Widget demo

It’s basically a widget which handles initialization, state changes, code clean-ups and all the other animation boilerplate code, keeping you in the driver’s seat by allowing you control the animations at each interval(literally). It’s a real time-saver which takes care of animations and let’s you concentrate on other important aspects of your app.

How to use it?

Row & Column are two of the most basic widgets in Flutter used to design any UI. Motion Widget supports both these widgets and can be used as their replacement.

Motion<T>(
children:<Widget>[]
)

As shown above, T type can be Row or Column. children can have a list of Flutter widgets as its value.

Now the question is : How will they animate? This brings MotionElement into the picture. It is a custom widget which works hand-in-hand with the Motion Widget. It contains all the animation information for a child widget and tells the Motion Widget to animate it accordingly.

Motion<T>(
children:<Widget>[
MotionElement(
child: Text("Hi")
),
Text("How are you?")
]
)

The child widgets which are supposed to animate should be wrapped with MotionElement widget. In the above code, Text widget which is the child of MotionElement will animate while the other one won’t.

Basically, that’s pretty much it! No animation stuff to deal with and nothing to dispose for avoiding memory leaks. Motion widget takes care of that. You might be wondering : How this allows developers “run the show”? These widgets have a bunch of other parameters for this. Let’s explore!

Motion & MotionElement : Deep dive

This concept revolves around the two widgets : Motion and MotionElement.

Motion

This can be used as a Row or a Column and has all their properties. It also has parameters for controlling animation:

  • durationMs : It accepts an integer which will be the animation duration (in milliseconds). By default, this value will be 1000.
  • shouldRepeat : If we need to repeat the animation, we can set this property as true.
  • isAutomatic : By default, motion widget will start animation automatically. We can control that using this flag.
  • exitConfigurations : This accepts a MotionExitConfigurations object. Using this, we can configure exit animation. It has properties like durationMs, displacement, orientation and mode. This transition will be applied to the entire Motion Widget. It provides you with a controller to control the exit animation.

MotionElement

This is used as a parent of any element inside Motion Widget which is supposed to animate. This has following properties to play with:

  • mode : The is used to define mode of animation. Currently, Motion Widget supports TRANSLATE, FADE and TRANSLATE_FADE(translate + fade) modes.
  • orientation : This defines the direction of the motion. It can be LEFT, RIGHT, UP or DOWN.
  • displacement : It takes a double value which defines the translation value of the widget. This will be taken into consideration only if the widget is to be translated.
  • interval : This property is very important when is comes to controlling animations granularly. It accepts Flutter’s Interval object. We can mention begin and end time values to delay the animation as per the needs. The values should be between 0.0 and 1.0. We can also specify curves to have complex interpolations.

Enough said! Show me the code

The following code snippet shows how to use Motion Widget to achieve similar effect as the one provided by Android’s LayoutAnimationController.

Motion Widget example

This is the code for feature list screen which can be seen in the GIF that I posted above. The code looks almost the same as the one when we use simple Column widget, doesn’t it?

Behind the scenes

Motion widget processes each of its child and assigns an AnimatedBuilder to it according to MotionElement’s configuration. This can be seen in the below code snippet.

Signing off

I have converted this widget into a package which can be found here along with a Github example. Motion Widget is still in it’s infant-from and I would love to have any PR from the beautiful, talented Flutter community to improve or change any of its features making it more effective.

That’s all for now. If you found this article to be helpful, please don’t forget to smash the clap button. Have an animated day ahead! 😃

--

--

Sumeet Rukeja
Flutter Community

Technology enthusiast, a F.R.I.E.N.D.S fan & a gamer