flutter sizetransition menu

What is the Flutter SizeTransition widget and how to use it

What is the SizeTransition in Flutter

The Flutter SizeTransition is a widget that allows you to animate the size of a child widget. This can be useful if you want to gradually increase or decrease the size of a widget over time, for example, to create a “zoom in” or “zoom out” effect.

The animation can be controlled by specifying a curve and a duration. The curve determines how the animation progresses over time, for example, whether it starts slow and then speeds up or starts fast and then slows down. The duration is how long the animation takes to complete.

You can use the SizeTransition widget by wrapping the child widget you want to animate in a SizeTransition widget and providing the animation details.

It is important to note that this widget only animates the size of the child, not its position, so if you want to animate the position too you would need to use another widget such as PositionTransition.

Where the SizeTransition widget can be used in Flutter

Here are a few examples of where the SizeTransition widget can be used in Flutter:

  1. Zoom In/Out effect: You can use the SizeTransition widget to create a zoom-in/out effect on an image. By gradually increasing or decreasing the size of the image over time, you can create the illusion that the image is getting closer or farther away.
  2. Expand/Collapse effect: You can use the SizeTransition widget to create an expand/collapse effect on a container. By gradually increasing or decreasing the size of the container over time, you can create the illusion that the container is opening or closing.
  3. Loading animation: You can use the SizeTransition widget to create a loading animation. By gradually increasing and decreasing the size of a loading icon over time, you can create the illusion that the icon is pulsating or “breathing”.
  4. Reveal effect: You can use the SizeTransition widget to create a reveal effect. By gradually increasing the size of a widget over time, you can create the illusion that the widget is being revealed from underneath another widget.
  5. Progress Indicator: You can use the SizeTransition widget to create an animation for a progress indicator. By gradually increasing the size of an indicator over time, you can create the illusion that the indicator is filling up as the progress increases.
  6. Card Flip Animation: You can use the SizeTransition widget to create a card flip animation. By gradually increasing and decreasing the size of a card over time, you can create the illusion that the card is flipping over.
  7. Pop-up Animation: You can use the SizeTransition widget to create a pop-up animation. By gradually increasing the size of a widget over time, you can create the illusion that the widget is popping up from a smaller size.
  8. Carousel Animation: You can use the SizeTransition widget to create a carousel animation. By gradually increasing and decreasing the size of images or widgets over time, you can create the illusion that the images or widgets are rotating in a carousel.
  9. Tab Bar Animation: You can use the SizeTransition widget to create a tab bar animation. By gradually increasing and decreasing the size of tabs over time, you can create the illusion that the tabs are being selected or deselected.
  10. Loader Animation: You can use the SizeTransition widget to create a loader animation. By gradually increasing and decreasing the size of a loading icon over time, you can create the illusion that the icon is spinning or rotating.
  11. Fade-In/Out Animation: You can use the SizeTransition widget to create a fade-in/out animation. By gradually increasing and decreasing the size of a widget over time, you can create the illusion that the widget is fading in or out.
  12. In-App Notification Animation: You can use the SizeTransition widget to create an animation for in-app notifications. By gradually increasing the size of the notification over time, you can create the illusion that the notification is popping up from the bottom of the screen.
  13. Sliding Animation: You can use the SizeTransition widget to create a sliding animation. By gradually increasing and decreasing the size of a widget over time, you can create the illusion that the widget is sliding in or out from the side of the screen.
  14. Swipe Animation: You can use the SizeTransition widget to create a swipe animation. By gradually increasing and decreasing the size of a widget over time, you can create the illusion that the widget is being swiped in or out of the screen.
  15. Scroll Animation: You can use the SizeTransition widget to create a scroll animation. By gradually increasing and decreasing the size of a widget over time, you can create the illusion that the widget is scrolling up or down on the screen.

Note: these are examples, you can use this widget for many other scenarios, the most important thing is to have a good imagination and creativity when using the SizeTransition widget.

How to use the Flutter SizeTransition widget

To use the Flutter SizeTransition widget, you will need to follow these steps:

  1. Wrap the child widget that you want to animate in a SizeTransition widget. You can do this by creating a new instance of the SizeTransition widget and passing the child widget as an argument to the constructor.
  2. Set the sizeFactor property of the SizeTransition widget. This property controls the size of the child widget during the animation. You can set this property to an Animation object, which can be created using the AnimationController class.
  3. Create an AnimationController object and set its duration. The duration is how long the animation will take to complete.
  4. Bind the AnimationController’s value to the sizeFactor property of the SizeTransition widget. This will ensure that the child widget’s size changes as the animation progresses.
  5. Call the forward() method of the AnimationController to start the animation.
  6. Optionally, you can set the curve property of the AnimationController, this property determines how the animation progresses over time.
  7. When the animation is complete, you should dispose of the AnimationController object to free up resources.

This code is a simple example of how to use the SizeTransition widget in Flutter:

import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {

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

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {

  late final AnimationController _controller = AnimationController(
    duration: const Duration(seconds: 3),
    vsync: this,
  )..repeat();
  late final Animation<double> _animation = CurvedAnimation(
    parent: _controller,
    curve: Curves.fastOutSlowIn,
  );
  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
        appBar: AppBar(
          title: Text('flutterassets.com'),
        ),
        body: Center(
          child: SizeTransition(
            sizeFactor: _animation,
            child: Image.asset("assets/logo.png"),
          ),
        )
    );
  }
}

Variables

  • final AnimationController _controller: A variable of type AnimationController that is used to control the animation. It’s created with a duration of 3 seconds and the vsync is set to this, which is the current state. AnimationController is set to repeat indefinitely by using ..repeat() after creating it.
  • final Animation<double> _animation: A variable of type Animation<double> that is used to store the animation. It’s created using the CurvedAnimation class and its parent is the _controller, it also uses the Curves.fastOutSlowIn curve, this means that the animation will start slow and speed up as it progresses.

void dispose()

  • _controller.dispose(): This is used to dispose the animation controller when the state is no longer needed to free up resources.

build

  • Scaffold: The Scaffold widget is the basic layout structure of the screen, it provides a white background and a top app bar.
  • AppBar: The AppBar widget is a top app bar that contains the title of the screen.
  • SizeTransition: The SizeTransition widget is used to change the size of the logo image over time based on the animation that is passed to the sizeFactor property.
  • Image: The Image widget is used to display the logo image.

The SizeTransition widget is used to change the size of the logo image over time based on the animation that is passed to the sizeFactor property. The sizeFactor property accepts an animation of type Animation<double> which is the _animation variable that we created earlier.

Animate the size of the image with SizeTransition in Flutter

import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {

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

class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}

class MyHomePage extends StatefulWidget {

@override
State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {

late final AnimationController _controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
);
late final Animation<double> _animation = CurvedAnimation(
parent: _controller,
curve: Curves.fastOutSlowIn,
);

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

@override
Widget build(BuildContext context) {

return Scaffold(
appBar: AppBar(
title: Text('flutterassets.com'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
ElevatedButton(
child: Text('Click me'),
onPressed: () {
if (_controller.isCompleted) {
_controller.reverse();
} else {
_controller.forward();
}
},
),
SizeTransition(
sizeFactor: _animation,
child: Image.asset("assets/logo.png"),
),
],
)
);
}
}

Variables

  1. _controller: This is an instance of the AnimationController class. It controls the animation by providing methods to start, stop, and reverse the animation. In this code, it is set to have a duration of 2 seconds and is linked to the lifecycle of the _MyHomePageState class through the vsync: this property.
  2. _animation: This is an instance of the Animation class and is a child of the _controller. It defines the curve of the animation, in this case, it is set to Curves.fastOutSlowIn which means animation will start fast and end slow.

void dispose()

The dispose() method is used to release resources that are no longer needed by the app. In this specific code, it is used to release the resources associated with the _controller object.

The dispose() method is called when the widget is removed from the widget tree. This happens when the user navigates to another screen, for example. By releasing the resources associated with the _controller object, it ensures that the app does not continue to use unnecessary resources, which can improve performance and prevent memory leaks.

It calls _controller.dispose() to release the resources associated with the _controller object, and then calls super.dispose() to ensure that any other resources that need to be released are properly disposed.

Widget build

  1. Scaffold : The Scaffold widget provides a basic layout structure for the app and includes an app bar and a body. The app bar is represented by the AppBar widget and includes a title, in this case ‘flutterassets.com’.
  2. AppBar: This widget creates a Material Design app bar. It takes a title property that is used to set the text of the app bar.
  3. Column: This widget organizes widgets vertically. It takes an array of widgets as children and positions them in a vertical list. The mainAxisAlignment property is set to MainAxisAlignment.start, which means the children will be placed at the start of the column.
  4. ElevatedButton: This widget creates a Material Design raised button. It takes a child property that is used to set the text of the button and an onPressed property which is a callback function that is called when the button is pressed. In this code, when the button is pressed, it will check if the animation is completed. If it is completed, it will reverse the animation. Otherwise, it will forward the animation.
  5. SizeTransition: This widget animates the size of a child. It takes a sizeFactor property that is used to set the size factor of the animation and a child property that is used to set the child widget. In this code, it’s sizeFactor property is set to _animation and the child property is set to an Image widget. SizeTransition will animate the size of the image according to the _animation curve, which is defined by the _animation variable.
  6. Image.asset : This widget used to display an image from the assets bundle. The Image.asset constructor takes a single argument, which is a string representing the path to the image file in the assets bundle. In this code, it’s using "assets/logo.png" which means it will look for the image with the name logo.png inside the assets folder.

How it works

When the app is run, it will display a button labelled “Click me” and an image. When the button is clicked once, it will cause the image to animate and become larger in size. The animation is defined by the _animation variable, which uses a CurvedAnimation with a fastOutSlowIn curve. This means that the animation will start quickly, slow down in the middle, and then speed up again towards the end.

When the button is clicked again while the animation is still running, it will reverse the animation and the image will become smaller in size until it reaches its original size. The _animation variable is controlled by the _controller variable, which is an instance of the AnimationController class.

When the button is clicked again after the animation has completed, it will start the animation again and the image will become larger in size.

The _controller.isCompleted check is used to check the status of the animation. If the animation is completed, it will call _controller.reverse() to reverse the animation. Otherwise, it will call _controller.forward() to start the animation.

It’s worth noting that the AnimationController is a special type of Animation that can be used to control the animation, like starting and stopping it. Also, the SingleTickerProviderStateMixin is used to provide a single ticker to the state.

Create a menu with the SizeTransition widget in Flutter

flutter sizetransition menu

This is a simple menu created with SizeTransition widget:

import 'package:flutter/material.dart';

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

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

class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
late final AnimationController _controller = AnimationController(
duration: const Duration(milliseconds: 200),
vsync: this,
);
late final Animation<double> _animation = CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
);
bool _isMenuOpen = false;

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

@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('flutterassets.com'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.menu),
onPressed: () {
if (_controller.isCompleted) {
_controller.reverse();
_isMenuOpen = false;
} else {
_controller.forward();
_isMenuOpen = true;
}
},
)
],
),
body: Stack(
children: <Widget>[
GestureDetector(
onTap: () {
if(_isMenuOpen){
_controller.reverse();
_isMenuOpen = false;
}
},
child: Container(
height: double.infinity,
// color: Colors.transparent,
child: Container(
alignment: Alignment.topCenter,
child: Image.asset("assets/logo.png")),
),
),
Positioned(
right: 0,
top: 0,
child: SizeTransition(
sizeFactor: _animation,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
border: Border.all(color: Colors.black, width: 1),
image: DecorationImage(
image: AssetImage("assets/logo.png"),
fit: BoxFit.cover,
)
),
width: 250,
// width: double.infinity,
height: 300,
padding: EdgeInsets.all(20),
child: Column(
children: <Widget>[
ListTile(
title: Text("Menu Item 1", style: TextStyle(fontWeight: FontWeight.w900),),
onTap: (){
_controller.reverse();
_isMenuOpen = false;
},
),
ListTile(
title: Text("Menu Item 2", style: TextStyle(fontWeight: FontWeight.w900),),
onTap: (){
_controller.reverse();
_isMenuOpen = false;
},
),
ListTile(
title: Text("Menu Item 3", style: TextStyle(fontWeight: FontWeight.w900),),
onTap: (){
_controller.reverse();
_isMenuOpen = false;
},
),
Spacer(),
ListTile(
title: Text("Close", style: TextStyle(fontWeight: FontWeight.w900),),
onTap: (){
_controller.reverse();
_isMenuOpen = false;
},
),
],
),
),
),
)
],
),
),
);
}
}

This is a code that demonstrates how to create an animation for a menu that slides in from the right side of the screen when an icon button is pressed.

  1. The first thing that is defined in the code is the AnimationController and Animation. AnimationController is responsible for controlling the animation and Animation is the animation that is being controlled. The duration property is set to 200 milliseconds, and the vsync property is set to “this”, which means that the animation will be synced with the app’s display.
  2. _isMenuOpen variable is being set to false, which is used to check if the menu is open or not.
  3. dispose() method is being override to dispose of the animation controller when the widget is disposed.
  4. build() method is the main method that creates the layout of the app.
  5. A MaterialApp is created, with a Scaffold widget as the home. The Scaffold widget has an AppBar with a title and an IconButton with an icon of three horizontal lines, which is commonly used as a menu icon.
  6. When the menu icon is pressed, an onPressed callback is called. The if statement checks if the animation is completed or not. If it is completed, the animation controller will reverse the animation, which will close the menu and _isMenuOpen variable is set to false. If the animation is not completed, the animation controller will forward the animation, which will open the menu and _isMenuOpen variable is set to true.
  7. A Stack widget is created as the body of the Scaffold widget. The Stack widget has two children: a GestureDetector and a Positioned widget.
  8. The GestureDetector is used to detect taps on the screen. If the menu is open and the screen is tapped, the animation controller will reverse the animation and _isMenuOpen variable is set to false.
  9. The Positioned widget is used to position the menu on the screen. The right and top properties are set to 0, which positions the menu at the top-right corner of the screen. The child of the Positioned widget is a SizeTransition widget.
  10. The SizeTransition widget is used to animate the size of its child. The sizeFactor property is set to the animation defined earlier, and the curve property is set to Curves.easeInOut, which creates a smooth animation.
  11. The child of the SizeTransition widget is a Container widget that has a decoration property, which is used to define the appearance of the menu. The width and height properties are set to 250 and 300 respectively. The child of the container is a Column widget that contains a list of ListTile widgets which represents the menu items.
  12. Each of the ListTile widgets has a title property that displays the title of the menu item and an onTap callback that is called when the menu item is tapped. When a menu item is tapped, the animation controller will reverse the animation and _isMenuOpen variable is set to false, closing the menu.

In summary, this code defines an animation for a menu that slides in from the right side of the screen when an iconbutton is pressed, and also allows for the menu to be closed when the screen is tapped or when a menu item is selected.

The animation is controlled by the AnimationController and Animation widgets, and the layout of the menu is created using the Positioned and SizeTransition widgets. The GestureDetector widget is used to detect taps on the screen and the ListTile widgets are used to create the menu items.

Overall, this code demonstrates a basic implementation of a sliding menu animation in a Flutter app.