Flutterexperts

Empowering Vision with FlutterExperts' Expertise
Using AnimatedPositioned Widget In Flutter

Flutter is an amazing UI tool kit used to create beautiful applications with ease. Flutter provides us a variety of widgets that can be used to create animated and customs widgets.

In this blog, we shall explore AnimatedPositioned widget and we will create a custom screen view demo using Animation and AnimatedPositioned. So let’s get started.

Module Demo :

Note: You can read the full blog here.


Table of Content

:: AnimatedPositioned Widget

:: MainSreen Class

:: Intializing Objects and variables

:: Stack

:: Other Widgets

:: Building dashboard

:: main.dart


AnimatedPositioned Widget

This widget is used to animate the position of a widget implicitly. It fits into a stack list of children just like a regular Positioned widget. It animates the given child position according to the curve, position, and duration specified by the user.

The properties of AnimatedPositioned are: left, right,top, bottom, duration, child,width, onEnd, height , curve and key.

Read more about Animation:

Introduction to Animation in Flutter
Let’s learn how to animate flutter widgets…medium.com

Creating a Custom Sreen View

Creating a MainSreen stateful class with SingleTickerProviderStateMixin

SingleTickerProviderStateMixin used when you have only one Animation Controller in your widget and its job is to provide with ticker value to the Stateful Widget.

class MainScreen extends StatefulWidget {
@override
_MainScreenState createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen> with SingleTickerProviderStateMixin{
@override
Widget build(BuildContext context) {
return Container();
}
}

Initializing Objects and variables

Here we have created 4 bool variables to control the animated position of the widget and _controller the object is used to control the animation of the widget and duration controls the animation duration of the widget.

class MainScreen extends StatefulWidget {
@override
_MainScreenState createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen> with SingleTickerProviderStateMixin{

bool isLeftCollapsed = true;
bool isRightCollapsed = true;
bool isTopCollapsed = true;
bool isBottomCollapsed = true;
double screenWidth, screenHeight;
final Duration duration = const Duration(milliseconds: 300);
AnimationController _controller;

@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: duration);
}

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

@override
Widget build(BuildContext context) {
return Scaffold();
}
}

Stack

AnimatedPostioned widget can only be only inside the stack children widgets, so we need to use Stack widget to wrap all our widgets inside it.

Scaffold(
body: Stack(
children: <Widget>[
upperBar(),
sideBar(),
bottomBar(),
AnimatedPositioned(
left: isLeftCollapsed ? 0 : 0.5 * screenWidth,
right: isRightCollapsed ? 0 : -0.2 * screenWidth,
top: isTopCollapsed ? 0 : 0.1 * screenHeight,
bottom: isBottomCollapsed ? 0 : 0.1 * screenHeight,
duration: duration,
child: dashboard(context)),
],
),
);

Other Widgets

These widgets are used as a part of the demo UI. bottomBar() , upperBar(),sideBar()widget is used at the bottom of our screen, top of our screen, and left side of the screen respectively.

Widget bottomBar() {
return Positioned(
bottom: 10,
left: 30,
child: Row(
children: [
Text(
"Reset Password",
style: TextStyle(color: Colors.grey, fontSize: 25),
),
SizedBox(
width: 60,
),
Container(
width: 100,
height: 40,
child: Center(
child: Text(
"Log Out",
style:
TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
)),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), color: Colors.blue),
)
],
));
}

Widget sideBar() {
return Positioned(
left: 30,
top: 250,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Home",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.blue,
fontSize: 25),
),
SizedBox(
height: 10,
),
Text(
"My Account",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.blue,
fontSize: 25),
),
SizedBox(
height: 10,
),
Text(
"My Orders",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.blue,
fontSize: 25),
),
SizedBox(
height: 10,
),
Text(
"Settings",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.blue,
fontSize: 25),
),
],
));
}

Widget upperBar() {
return Positioned(
top: 40,
left: 30,
child: Row(
children: [
CircleAvatar(
child: Icon(Icons.person_outline),
),
SizedBox(
width: 10,
),
Text(
"User name",
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
),
SizedBox(
width: 80,
),
Container(
width: 100,
height: 40,
child: Center(
child: Text(
"View Profile",
style:
TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
)),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), color: Colors.blue),
)
],
));
}

Building dashboard

dashboard() widgets is used at the top of our Stack this widget is going to be animated. In this widget I have created an icon Button the AppBar that will animate the position of dashborad() the widget from the top, bottomand left side of the screen, this can also be used as a custom draweras it looks like a side drawer. Also, we have Animated the top and bottom of the dashboard() .

Logic used

When the user will tap the menu icon the animation will start and isTopCollapsed, isBottomCollapsed, isLeftCollapsed variables will set to there not values i.e. if they are true then they will set to false and vise versa.

When all three variables are false the AnimatedPostioned widget that we have used inside our Stack will animate the position of dashborad() widgets.

AnimatedPositioned(
left: isLeftCollapsed ? 0 : 0.5 * screenWidth,
right: isRightCollapsed ? 0 : -0.2 * screenWidth,
top: isTopCollapsed ? 0 : 0.1 * screenHeight,
bottom: isBottomCollapsed ? 0 : 0.1 * screenHeight,
duration: duration,
child: dashboard(context)),

Widget dashboard(context) {
return SafeArea(
child: Material(
type: MaterialType.card,
animationDuration: duration,
elevation: 8,
child: Scaffold(
appBar: AppBar(
elevation: 0,
title: Text('MarketWatch'),
actions: [
IconButton(
icon: isTopCollapsed
? Icon(
Icons.keyboard_arrow_down_outlined,
size: 40,
color: Colors.white,
)
: Icon(
Icons.keyboard_arrow_up_outlined,
size: 40,
color: Colors.white,
),
onPressed: () {
setState(() {
isTopCollapsed
? _controller.forward()
: _controller.reverse();
isTopCollapsed = !isTopCollapsed;
});
},
)
],
leading: IconButton(
icon: isLeftCollapsed ? Icon(Icons.menu) : Icon(Icons.clear),
onPressed: () {
setState(() {
if (isLeftCollapsed) {
_controller.forward();
} else {
_controller.reverse();
}
isTopCollapsed = !isTopCollapsed;
isLeftCollapsed = !isLeftCollapsed;
isBottomCollapsed = !isBottomCollapsed;
});
}),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
isBottomCollapsed
? _controller.forward()
: _controller.reverse();
isBottomCollapsed = !isBottomCollapsed;
});
},
child: isBottomCollapsed
? Icon(
Icons.keyboard_arrow_up_outlined,
size: 40,
)
: Icon(
Icons.keyboard_arrow_down_outlined,
size: 40,
),
),
),
),
);
}

main.dart file

https://gist.github.com/anmolseth06/bd391505d4c257a2f74a199ac2f47231#file-main-dart


Thanks for reading this article ❤

If I got something wrong? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.

If we got something wrong? Let me know in the comments. we would love to improve.

FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! You can connect with us on Facebook, GitHub, Twitter, and LinkedIn for any flutter related queries.

We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences!.

Leave comment

Your email address will not be published. Required fields are marked with *.