Ahoy, my friends, I hope you all are doing good.
Our today's topic to learn is about,
Stateful Widget
Animated Container
Future Delay
Hey, don't you think that these are some boring topics.
These are very much interesting topics to learn.
So What are we waiting for?
Let's Get Started.
So,
What is a Stateful Widget?
A widget that has a mutable state.
Hey, but What is State?
The state is information that one can read synchronously when the widget is built and might change during the lifetime of the widget.
Didn't Understand?
Will help you.
Think about our previous post where we built a login page for our users.
What if we can write Welcome and Username both after the user provides his username?
Cool naa?
But this thing cannot be handled using the stateless widget.
So now we have to use the Stateful Widget
for performing this task.
Ready?
Jump in your code editors and let's change that Stateless Widget
into the Stateful Widget
.
But wait, How are we going to do that?
Click on the name of our stateless class, you will see a bulb icon, click on it!
We will be talking about Mixin
in our later articles.
So, now you created the Stateful widget
.
Now create a variable of your choice inside here,
Oops, I haven't taught you what are variables
In simple words variable is a place where a value is stored.
For example, My name isGulshan
and I am aDeveloper
. So hereGulshan
is a variable andDeveloper
is the value.
There are various types in a variable like I am male. And likewise, there are specific types of variables that will store numbers, characters, and so on.
Likeint
for storing integer values,char
for storing characters, andstring
for storing strings.
In dart you can simply usevar
as a type and dart will automatically select the type for your declared variable according to the given value.
Getting back to our point, our variable name
will store the username of the user.
Now add $name
inside the text widget
. Like this,
Text(
"Welcome $name",
style: TextStyle(
fontSize: 21.0,
fontWeight: FontWeight.bold,
),
)
What it does is, It will check the variable for writing the value inside our text widget.
Hey, but we are not done yet.
We need to modify our text form field Widget
for storing the given value into our variable.
Here's how you can do this,
TextFormField(
onChanged: (value) {
name = value;
},
decoration: InputDecoration(
labelText: "Username or Email",
hintText: "you@yourmail.com",
),
)
We discussed decoration in our previous article, but there's a change. I used the onChanged
argument.
What does it do?
It will perform certain tasks when the input inside our Field is changed.
Here it is assigning the value to our variable name
. That is the username.
Now you may try clicking the F5
button or try running flutter run in your terminal to show the changes, or you may use the hot reload feature of flutter if you are running your flutter application while following this post.
But you may notice, it's not working.
But it is working. The problem is, that it is not rebuilding the application or our page while we are making some changes.
So, how to tell our application to rebuild the specific page while making some changes?
It's easy.
We will use setState
to inform the framework that the user made some changes.
Its usage,
You may notice, that I wrapped the assigning task with our setState
function.
Now do a hot reload or restart your flutter application and try doing some changes in the username field.
walla!
You successfully learned about the Stateful widget and Setstate usage.
Now let's learn about Containers in flutter
I won't bore you with the usual definition of containers in flutter.
Imagine a Container or Box whichever you like. What is its task??
To store something right?
It can be anything. Here we will be using the
container widget
for building our own button, as we love to get our hands dirty right?
Enough talk, let's build our own button.
Here's my code, please check the comments I added for better understanding,
Container(
width: 150,
height: 50,
alignment: Alignment.center, // for alligning the child in centre.
child: Text(
"Login",
style: TextStyle(
color: Colors.white, //color of text, since it is black by default. Which looks ugly to me
fontSize: 18, // You may experiment with numbers :)
fontWeight: FontWeight.bold, // So that our login button looks a bit subtle.
),
),
decoration: // design time.
BoxDecoration(
color: Colors.purple, // so that it will match with the default color of our application.
borderRadius: BorderRadius.circular(10), // As the sharp edges of our button is looking a bit ugly.
),
)
But there's a problem, Our button can't perform the click operation.
How to fix this issue?
We have two options, either we can use
GestureDetector
or InkWell
.
Which one is best?
Both are best for their specific usage, but for now, we will be using
InkWell
since It can provide us a plethora of options to customize our button.
So here we go,
InkWell(
child: Container(
width: 150,
height: 50,
alignment: Alignment.center,
child: Text(
"Login",
style: TextStyle(
color: Colors
.white,
fontSize: 18,
fontWeight:
FontWeight.bold,
),
),
decoration:
BoxDecoration(
color: Colors
.purple,
borderRadius: BorderRadius.circular(
10),
),
),
onTap: () {
Navigator.push( // routing our page to homepage
context,
MaterialPageRoute(
builder: (context) => MyHomePage(title: "Gulshan Yadav"),
),
);
},
)
Here's how it's going to look like,
Yaa, I know there's not so much of a difference we created.
But at least you learned how to use a container to build your own button or whatever you want.
Let's dig deeper,
What is Animated Container? According to documentation, I read.
The AnimatedContainer is a widget that will automatically animate between the old and new values of properties when they change using the provided curve and duration.
I know you are having a hard time understanding this definition.
Even I had one.
What this definition say is, It is a container that can animate from old value of properties to New values of properties.
You can think of, like when you click our login button, the size of the button can be changed between some specific time duration. Or whatever you can imagine that you want to animate.
Let's begin,
Create a variable named changedButton
with the value false
. It is a boolean variable.
A variable with the type bool means, it will only deal with true and false or 1 or 0's.
And let's use that variable in our code,
Now look at my code and do check the comments for better understanding,
InkWell(
child: AnimatedContainer(
duration: Duration(seconds: 1), // According to definition, duration is the
// important thing to consider while using Animatied container
width: changedButton ? 50 : 150, // If changedButton is true then change
// the width to 50 else 150
height: changedButton ? 4 : 50, // Same as above
alignment: Alignment.center,
child: Text(
"Login",
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
decoration: // design time.
BoxDecoration(
color: Colors.purple,
borderRadius: BorderRadius.circular(10),
),
),
onTap: () {
setState(() {
changedButton = true; // After tapping on our own button
// change the value to true and perform some operations.
});
// Removing this part for the sake of understanding, what's happening.
// Navigator.push(
// // routing our page to homepage
// context,
// MaterialPageRoute(
// builder: (context) =>
// MyHomePage(title: "Gulshan Yadav"),
// ),
// );
},
splashColor: Colors.purple[
100], // Long press the button to see the usage of splash color
),
What this code does is, after we tap on our login button it will change the value inside our variable to true. In our case changedButton
.
But you may ask, why did I comment on our navigator part?
Because if there's a navigator part involved, the animation part is totally ignored our page is directly moved to our homepage or next page.
For attaining both animation and navigation through pages, we need something else.
Here comes the Future delay
widget to help us.
here's how I used it,
onTap: () async {
setState(() {
changedButton = true; // After tapping on our own button
// change the value to true and perform some operations.
});
await Future.delayed(Duration(seconds: 1));
Navigator.push(
// routing our page to homepage
context,
MaterialPageRoute(
builder: (context) =>
MyHomePage(title: "Gulshan Yadav"),
),
);
}
You may notice that I have used async
and await
keywords, what are those?
Async
Simply means occurring at the same time.
AndAwait
means to wait. i.e. to wait for a certain operation to over.
I want you to do some tweaks to the application so that it will help you in your learning.
Just play around and you will learn a lot.
In this article, we learned about the stateful widget, set-state usage, and its importance, Building our own button using a container, and also tried future delay for performing some small animations.
In the next article, we will be exploring more flutter widgets you are supposed to know.
until then, stay home stay safe.
Cya :)