Animation
Well-designed animation makes a UI feel intuitive, contributes to the look and feel of a polished app, and improves the user experience. Flutter’s animation support makes it easy to implement simple and complex animations. The Flutter SDK includes many Material Design widgets that include standard motion effects and you can easily customize these effects to personalize your app.
In React Native, Animated APIs are used to create animations.
In Flutter, use the Animation
class and the AnimationController
class. Animation
is an abstract class that understands its current value and its state (completed or dismissed). The AnimationController
class lets you play an animation forward or in reverse, or stop animation and set the animation to a specific value to customize the motion.
How do I add a simple fade-in animation?
In the React Native example below, an animated component, FadeInView
is created using the Animated API. The initial opacity state, final state, and the duration over which the transition occurs are defined. The animation component is added inside the Animated
component, the opacity state fadeAnim
is mapped to the opacity of the Text component that we want to animate, and then, start()
is called to start the animation.
// React Native
class FadeInView extends React.Component {
state = {
fadeAnim: new Animated.Value(0) // Initial value for opacity: 0
};
componentDidMount() {
Animated.timing(this.state.fadeAnim, {
toValue: 1,
duration: 10000
}).start();
}
render() {
return (
<Animated.View style={{...this.props.style, opacity: this.state.fadeAnim }} >
{this.props.children}
</Animated.View>
);
}
}
...
<FadeInView>
<Text> Fading in </Text>
</FadeInView>
...
To create the same animation in Flutter, create an AnimationController
object named controller
and specify the duration. By default, an AnimationController
linearly produces values that range from 0.0 to 1.0, during a given duration. The animation controller generates a new value whenever the device running your app is ready to display a new frame. Typically, this rate is around 60 values per second.
When defining an AnimationController
, you must pass in a vsync
object. The presence of vsync
prevents offscreen animations from consuming unnecessary resources. You can use your stateful object as the vsync
by adding TickerProviderStateMixin
to the class definition. An AnimationController
needs a TickerProvider, which is configured using the vsync
argument on the constructor.
A Tween
describes the interpolation between a beginning and ending value or the mapping from an input range to an output range. To use a Tween
object with an animation, call the Tween
object’s animate
method and pass it the Animation
object that you want to modify.
For this example, a FadeTransition
widget is used and the opacity
property is mapped to the animation
object.
To start the animation, use controller.forward()
. Other operations can also be performed using the controller such as fling()
or repeat()
. For this example, the FlutterLogo
widget is used inside the FadeTransition
widget.
// Flutter
import 'package:flutter/material.dart';
void main() {
runApp(Center(child: LogoFade()));
}
class LogoFade extends StatefulWidget {
_LogoFadeState createState() => _LogoFadeState();
}
class _LogoFadeState extends State<LogoFade> with TickerProviderStateMixin {
Animation animation;
AnimationController controller;
initState() {
super.initState();
controller = AnimationController(
duration: const Duration(milliseconds: 3000), vsync: this);
final CurvedAnimation curve =
CurvedAnimation(parent: controller, curve: Curves.easeIn);
animation = Tween(begin: 0.0, end: 1.0).animate(curve);
controller.forward();
}
Widget build(BuildContext context) {
return FadeTransition(
opacity: animation,
child: Container(
height: 300.0,
width: 300.0,
child: FlutterLogo(),
),
);
}
dispose() {
controller.dispose();
super.dispose();
}
}
Android |
IOS |
How do I add swipe animation to cards?
In React Native, either the PanResponder
or third-party libraries are used for swipe animation.
In Flutter, to add a swipe animation, use the Dismissible
widget and nest the child widgets.
child: Dismissible(
key: key,
onDismissed: (DismissDirection dir) {
cards.removeLast();
},
child: Container(
...
),
),
Android |
IOS |