Animations are a big part of the Flutter application. It makes an app sweet to the eyes and equally user-friendly. In this article, we will discuss in detail the Hinge animations. In Flutter there are two ways to work with animations namely:
- A pub package
- Animated Builder Widget
In this article, we will be working with the Animated Builder widget. A Hinge animation is a type of animation where an element can turn over with a sudden movement.
Steps to Implement Hinge Animation
Step 1 : Return Material App in main.dart() file
First, create MyApp() in StatelessWidget and in it return MaterialApp(). Now in MaterialApp() give the title of the app and add debugShowCheckModeBanner as false which will remove the debug banner in the app.
main.dart:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HingeAnimation(),
);
}
}
Step 2 : Create a new Stateful class called HingeAnimation
Create a stateful widget class with title as "GeeksForGeeks", backgroundColor, foregroundColor, and many more in appbar.
main.dart:
// Create a stateful widget
class HingeAnimation extends StatefulWidget {
@override
_HingeAnimationState createState() => _HingeAnimationState();
}
class _HingeAnimationState extends State<HingeAnimation>{
// The animation widget
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.green[300],
foregroundColor: Colors.white,
automaticallyImplyLeading: false,
title: Text("GeeksForGeeks"),
centerTitle: true,
),
body: //code ..
);
}
}
Step 3 : Initialize Animation controller and Animation values
Define each animation controller & animation values using and initialize them in initState(), because the framework will call this method exactly once for each state object it creates.
// Animation setup
late AnimationController _controller;
late Animation<double> _rotationAnimation;
late Animation<double> _slideAnimation;
late Animation<double> _opacityAnimation;
@override
void initState() {
super.initState();
// Initialize the AnimationController
_controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 2000),
);
// Setup the rotation animation
_rotationAnimation = Tween<double>(begin: 0.0, end: 0.15).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.0,
0.5,
curve: Curves.bounceInOut,
),
),
);
// Setup the slide animation
_slideAnimation = Tween<double>(begin: 100.0, end: 600.0).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.5,
1.0,
curve: Curves.fastOutSlowIn,
),
),
);
// Setup the opacity animation
_opacityAnimation = Tween<double>(begin: 1.0, end: 0.0).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.5,
1.0,
curve: Curves.fastOutSlowIn,
),
),
);
}
@override
void dispose() {
// Dispose the controller when the widget is disposed
_controller.dispose();
super.dispose();
}
Step 4 : Use those in Scaffold body
using AnimatedBuilder widget, we can apply those animations in scaffold body because it creates an animated builder.
AnimatedBuilder(
animation: _slideAnimation,
builder: (BuildContext context, Widget? child) => Container(
width: 200,
height: 150,
padding: EdgeInsets.all(0),
margin: EdgeInsets.only(
left: 100,
top: _slideAnimation.value,
),
child: RotationTransition(
turns: _rotationAnimation,
child: Center(
child: Text(
'GeeksForGeeks',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: Color.fromRGBO(
300,
150,
500,
_opacityAnimation.value,
),
),
),
),
),
),
),
Step 5 : Add a FloatingActionButton in HingeAnimation class
Add a FloatingActionButton to play the animation and a text to implement the animations inside the HingeAnimation class.
// The button to trigger the animation
floatingActionButtonLocation:
FloatingActionButtonLocation.miniCenterFloat,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.play_arrow),
backgroundColor: Colors.green[300],
onPressed: () {
_controller.forward();
},
),
To know more about FloatingActionButton in flutter refer this article: Flutter – FloatingActionButton
Complete Source Code
main.dart:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HingeAnimation(),
);
}
}
// Create a stateful widget
class HingeAnimation extends StatefulWidget {
@override
_HingeAnimationState createState() => _HingeAnimationState();
}
class _HingeAnimationState extends State<HingeAnimation>
with SingleTickerProviderStateMixin {
// Animation setup
late AnimationController _controller;
late Animation<double> _rotationAnimation;
late Animation<double> _slideAnimation;
late Animation<double> _opacityAnimation;
@override
void initState() {
super.initState();
// Initialize the AnimationController
_controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 2000),
);
// Setup the rotation animation
_rotationAnimation = Tween<double>(begin: 0.0, end: 0.15).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.0,
0.5,
curve: Curves.bounceInOut,
),
),
);
// Setup the slide animation
_slideAnimation = Tween<double>(begin: 100.0, end: 600.0).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.5,
1.0,
curve: Curves.fastOutSlowIn,
),
),
);
// Setup the opacity animation
_opacityAnimation = Tween<double>(begin: 1.0, end: 0.0).animate(
CurvedAnimation(
parent: _controller,
curve: Interval(
0.5,
1.0,
curve: Curves.fastOutSlowIn,
),
),
);
}
@override
void dispose() {
// Dispose the controller when the widget is disposed
_controller.dispose();
super.dispose();
}
// The animation widget
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.green[300],
foregroundColor: Colors.white,
automaticallyImplyLeading: false,
title: Text("GeeksForGeeks"),
centerTitle: true,
),
body: AnimatedBuilder(
animation: _slideAnimation,
builder: (BuildContext context, Widget? child) => Container(
width: 200,
height: 150,
padding: EdgeInsets.all(0),
margin: EdgeInsets.only(
left: 100,
top: _slideAnimation.value,
),
child: RotationTransition(
turns: _rotationAnimation,
child: Center(
child: Text(
'GeeksForGeeks',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: Color.fromRGBO(
300,
150,
500,
_opacityAnimation.value,
),
),
),
),
),
),
),
// The button to trigger the animation
floatingActionButtonLocation:FloatingActionButtonLocation.miniCenterFloat,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.play_arrow),
backgroundColor: Colors.green[300],
onPressed: () {
_controller.forward();
},
),
);
}
}
Output: