Flutter Animations Tutorial For Beginners

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we'll dive deep into animations using flutter we'll explore different techniques that will build a strong foundation in animation we'll begin with implicit animations which will teach us how to add smooth animations without the need for complex setups next we'll dive into explicit animations where we learn how to have complete control over every aspect of our animation allowing us to create unique effects after that we will explore page transitions where we learn the art of smoothly transitioning between different screens and finally we learn about custom painter and how we can animate something drawn using custom painter the prerequisite for this tutorial is the basics of Dart and flutter if you're not already familiar with it you can watch my 20 are free tutorial link to the video will be mentioned in the description or pin comment now let's get started so to get started you need to go to this URL the link will be mentioned in the description below then you need to click on this green code button copy this URL go to your terminal and migrate to the folder where you want to extract this project so I'll go to desktop and after that you need to run the command get clone followed by the URL you just copied so that we have the project up in our system after that we'll just migrate to that particular folder the animation starter code and open it in the code editor we want I'm going to open it in Visual Studio code and yeah there we have it now you might be wondering what this project is all about this is a starter code but what does the starter code contain we'll get to it but before that we need to run pubkit what does this Pub get well just click on this dialog if you see it otherwise press command J your terminal will open up then you need to run flutter Pub get what this flood up object does is it basically gets all the packages all the useful tools for you so that you can start running your project so if you go to pubspec.yaml you'll see all of these dependencies these Dev dependencies it gets that from pub.dev stores it in cash because of which we can run our project without any errors earlier you saw we had multiple problems but after running this one command all of our problems disappeared so after you've run this command let's just close the terminal we'll open the iOS simulator to see what's up and running so let's get it up and after it is up let's run it without debugging cool after we have that we are going to go to the lib folder and here you're going to see four folders and the main.dot file what are these well we can see custom painter example explicit and implicit examples and a page route Builder animation these are examples we're going to use in our video to understand animations so if you open implicit example you'll see animated color palette animated shopping cart animated tween animation Builder all of these are examples we are going to see to understand animations better so if you go to animated color palette and scroll around you'll see the code for color palette it's not actually animated we are going to animate this on our own in this tutorial I'm going to type it out nothing will be pre-written related to animations so this is just a color palette the UI for all of these things has already been written so that we don't waste much time on writing the UI which you can already write it on your own of course I'm going to explain all the code that is already written over here so that there's no confusion whatsoever so now that we have the iOS simulator up and running let's see what exactly is pre-written over here and what we need to do what animation we need to apply so that this looks better right so let's just close the terminal behind and there we have our app now in this app we have five squares each having a color of its own and when I click on this generate new palette button new colors appear over here every time I do that new colors appear over here and this looks good so what's the code for this let's dive into the code now so here in our code we are going to start with the UI we are not going to take a look at the logic first first we'll take a look at the UI and then we'll go to the logic then it will become simpler so we are returning a scaffold then we have an app bar so this portion right here then we have a centered column with main access alignment Dot Center so yeah we're just positioning everything in the center but the main thing to look at is this for Loop and this elevated button so let's go over the for Loop what is this for Loop doing well for Loop is iterating over current palette so we are just doing for color color in current palette because current palette is a list of colors so after iterating through the list we'll get access to a color and we're just displaying that color in a container of width and height 100 because of which we are able to get these containers so what is this current pilot value and how are we generating random colors so to understand that we'll go to the current palette variable so list of color current palette is equal to Generate random palette function so initially this is equal to this function and after that we are just doing final random is equal to random and then we are returning list dot generate 5. and then there's some functional error what is this doing well over here we are generating a list of five elements so let's dot generate first takes in a length which is the length of the list and for every element in this list we are running this function so for element 0 we are going to have this for element one we are going to have this for 2 3 4 we are going to run this every single time so what's happening in this function now so we are having color dot from rgbo r g and B values are Gordon from random dot next in 256. what this does is it generates random values between the integer 0 to 255 includes of 0 and 255 so every time this function runs we'll have a different value for RG and B between the value 0 to 255. and because of this we'll get a new color every single time the opacity is always one because it doesn't really matter to us we have enough combinations for us to get a different color every single time so this is what Generate random palette does and because of this we are able to display random colors every single time so what does this elevated button do well whenever we click over here a new color is generated how easy we just go to the regenerate palette function which is the on press of the celebrated button and here we are just doing such State current palette equal to Generate random palette just like we had it before over here initially it was equal to Generate random palette it called this function so it got different values now we are calling this again and doing such dates so that the build function rebuilds and we display a new UI right so I hope the explanation was easy to understand if not leave a question down below and I'll answer it now the question arises how do we want to animate this app of course I cannot tell it to you in words so let's see a demo of the solved example to understand what we need to do so one more time let's quickly see how the non-animated app looks like so if we click over here you see this is how the non-animated app looks like and this is how the animated app looks like you see the transition from color change is quite smooth so it gives a better user experience in non-animated app if you see it's quite weird to see these boxes being generated like this with animated the process becomes a lot smoother so this is what we are going to do so let's jump into the code and see how we can code this you might think that hey this is going to be a difficult job we basically need to convert one color from another color that's going to be hard right not really it's just two or three lines of changes you need to do and you're done animating the color palette that's how easy flutter makes it for us so when color a is changed from color a to color B we want that process to be smooth how can we do this well all our attention should go towards this container because this is what represents these squares where the color is changing if you want to change and animate this thing there should be a property inside of container allowing us to animate it right so let's try it out is there a property not really because container doesn't allow animations like implicit animations are not there in container well where is it then it should be in animated container so just container with animated before it that makes it an animated container an animated container contains all the properties of container plus some extra properties related to animation and that will make sure that your code is running but now you see there's an arrow the name parameter duration is required but there is no corresponding argument why is that the case well that's the case because we are forgetting to pass in a required argument of duration you see that's a required argument in animated container in container there's no such requirement so we'll just pass in duration but what is this duration well if you see over here it creates a container that animates its parameters implicitly the curve and duration arguments must not be null so it tells us the guidelines for duration but it doesn't really tell us what duration is but in the context we must be able to identify what this means this means how long is the animation going to be there is it going to be for one day one year or 100 milliseconds 10 seconds how long is it going to be there that's what we're trying to specify over here and thus it requires a class of duration to be passing an instance of duration so we'll just pass it in and here it gives us the opportunity type in milliseconds so we'll just type it in and I just want it to animate for 500 milliseconds you can do it with whatever value you prefer and this needs to be a const so let's save it and when we come away we try to generate a new palette you see our animation is completed just with two changes in our code it's done now let's just understand why this happens to understand this we need to go to the definition what is implicit animations implicit animations are animations that run or are triggered when the property inside of a widget changes the property that is changing over here is color why because every time this button is clicked on regenerate palette is clicked on the current palette changes right because we are doing such State such State means the build function will run again so current palette is equal to Generate random palette because of which this will also run and here we know that hey the previous color has now changed color a is now color B so I need to animate from that color a to the current color B in this specific time duration in 500 milliseconds I need to do that so the property color changed over here thanks to this function and because of that we were able to animate it properly that's how implicit animations work and that's how easy implicit animation is whenever you have a small task like this always go ahead with implicit animations when a certain property in your code is changing you can just go ahead and use this simple implicit animation widget that flutter provides you with that's not just animated container you can use you can also use other widgets like animated align animated container we already saw animated default textile and a lot of widgets we are still going to see some of them in these two examples but they are not all there are many and you can find the list on the web I'll show you how you can get that list of widgets that are implicit animated Widgets or they are just animated XYZ widgets okay so now the question comes yeah I understood this but what other properties are there in animated container that makes it different from container well there are quite a few and if we scroll down we can find this they are curve duration and on end so we already saw duration what is curve curve is basically how your animation is going to be approached like is it going to be slow in the beginning and fast in the end or is it going to be linear all the time how is it going to be reaching its final destination by default it is Linear by linear I mean let's say our duration is 500 milliseconds here right so what we want to do is and let me comment this out so that it's easier for all of us to remember so when 100 milliseconds is reached I want 20 of the animation to be done if I want if I'm on 200 milliseconds 40 of the animation should be done if I'm on 300 millisecond sixty percent of the animation should be done if I'm on 400 milliseconds eighty percent of the animation should be done and when I reach 500 millisecond the entire animation should be completed that's what I want this is linear because with every 100 millisecond increase in time you're increasing by 20 an animation so increasing linearly so how will this look like on a graph so let me draw these coordinate axes this is how it will look like on a graph why because let's say this is 100 milliseconds this is 200 this is 300 this is 400 and this is 500. in the same way this is 10 percent of the animation 20 30 40 50 60 70 80 90 100 these are not to scale obviously but I hope you will get the point so this was 100 millisecond and on 100 milliseconds we reached 20 percent right so here we are then we have 200 millisecond on 200 millisecond we reached somewhere over here then on 300 millisecond we were somewhere over a year on 400 millisecond we were somewhere over a year and on hundred percent or 600 milliseconds we were over a year so this is a linear graph this is how it will get completed and we can change that curve to something like this we can maybe do some configuration such that it reaches like this okay we reach the end point but like this it will be slow in the beginning and it will Pace up at the end so you can change that via curves argument over here let's just put it below the audition so we have curves and then you can decide for what curve you want using curves Dot and you have a bunch of options now I know these names aren't really intuitive as of now but you can say make sense of it is in out basically means that it will ease in and then it will be out and if you want to take a look at the graph you just hover over this click on the link that is attached to it and it will open up A visual representation of how this will look like this is how our animation will look like it will be a bit slow but it will take up pace at the end and again slow down at the end somewhere over here right now you can do that with other curves that are present we can have curves Dot ease into linear and to see this demonstration you can again open it it's attached for everything and this is looking more like our graph right but yeah you can make sense of it and it will display the changes over here if you see it changes right I mean there isn't much visibility I guess but if we change it to let's say 2000 milliseconds you'll see the difference it slowly changes but when we change it to linear and do this the difference is basically like in the start for Curves dot ease into linear we couldn't really see much differences but in linear we could see it in the beginning only because that's how the visual representation goes in the start this hardly does anything whereas linear would have been somewhere over here so I hope you understand the difference this is more of a mathematical stuff I hope you can understand that if not just play around with it get an intuitive sense of it and it will be good so this was about animated color palette there are lots of Curves you can try and keep trying it that's where I'm going to end this animated color palette as simple as it gets we just needed to change One widget now let's get into animated shopping cart button and see what it has for us so the next example that we're going to take a look at is the shopping cart button so we want to animate this button how well if we click on this button it should animate like this yeah you can see the error in between but that error will go away when you try to upload your app to apps to play store or whatever so we don't need to worry about that however we want this animation to occur you see this that's what I want so we can do this with our knowledge about implicit animation still now using animated container and stuff so I would recommend you to go ahead try this on your own it requires a bit of logic so if you're not able to do it don't feel bad about it but if you can then great so again just to show you the demo of the animation we want here it is so yeah let's get started by going to the code and making this shopping cart button work so the first thing I want here is I just want to copy the shopping cart button put it in main.dot file because this is the class that I want to see on the screen all right and then refresh it because then we get an error and now we have the shopping cart button so it's the same button but when we click on it nothing really happens because in animated shopping cart button we have not added any logic about the animation it's just a centered container with a fixed width and height with a blue color and Border radius and a shopping cart icon nothing else so that's what we're going to work on so let's get started so I have a video demo of the animation with me so that it becomes easier for us to decide what we need to animate because animation is like multiple things brought together to create a nice visual experience so we'll break that down and then make sure our animation works so let's look at the demo again if we see when the button is clicked on the first thing we notice is the blue color changes to Green so that's what we want to animate then again let's take a look at it when we click over here the shopping cart I can change this to a tick mark icon and this text appears okay and the last thing which might be a bit difficult to notice is that when you play this the Border radius also changes for example it's kind of rectangle Circle over here like the it seems kind of rectangle but it has a nice curve to it but when we come over here at the end it has a bigger border radius to itself it's more like a circle now or a oval so these are the components that make up this animation now that we've figured this out that was the most difficult part coding it is not so difficult as we have seen with implicit animations already so let's go over here stateless widget press Ctrl shift R if you're on Mac convert it to stateful widget and why have I converted it to a stateful widget because I want to change the width right because here it was small then your it became quite big so I want to change the width I also want to make sure that this color changes and all of this all of the things that we talked about should be done when a button is clicked on so what can we do well we can create separate variables for everything right so if I want the color I can just change the color again and again so what I'll do here is let's say color and let's say selected color is equal to colors.blue by default and when the user clicks on the button we'll just check if selected color is blue then we want to change it to Green and if it is green we want to change it to blue and then obviously we'll just shift it to animated container and it will animate that's cool right we can do that but the downside of it is we have to create separate variables for everything for example with the width is 80 right now later on we want to increase the width so we'll have to create a separate variable for width and a separate variable for Border radius and a separate variable to show an icon so that's not a good approach right we'll have to create so many different variables for so many things instead what we can do is create a Boolean variable saying is expanded and initially it will be set to false what this variable will do is basically saying like hey if the button is clicked on is expanded is true otherwise it is false and based on that we'll give values over here so if is expanded is true then I want the width to be let's say 300. otherwise it would be 80. now if you don't understand this don't worry I'll explain it to you but as of now since we've changed the container to animated container let's put duration over here so we have constant duration milliseconds and let's say the millisecond is 500 or 1000 whatever you prefer and thousand millisecond is just one second you can put that and just to Showcase it to you that animated container does nothing if no property of the animated container is changing so let's save it come over here and when you click nothing happens Okay cool so now what we want to do is first of all wrap our animated container in gesture detector because we want to detect the gesture like hey this animated container has been tapped on and if it has been tapped on I want to change the value of this expanded so I'll just set is expanded to not is expanded which basically means that it reverses the value of his expanded so if it's expanded is false then it will set it to true every time it is clicked on if it is true it will be clicked on and it will become false and doing this much is not enough we obviously want to call set state so let's put that up over here okay so such date will trigger a rebuild of this and because of that we'll be able to see the changes otherwise the changes won't be visible cool now what we want to do is make sure that our animated container starts depending on the value of is expanded what do I mean by that right now all the values are stationary static right none of it is dynamic none of it depends on is expanded since it does not depend its value does not change so we want to make sure that the value changes and the value should change when is expanded is true or false right so if it's expanded is true then I want the width to change so let's say it is 300 now if I save it the animation should happen right I'm changing from initial value of 80 to 300 because is expanded is set to true so let's restart I come over here and you see it increases that's perfect but I think 300 is a little bit too much let's go ahead with 200 right you see this works so the expanded material works here and we can do the same thing literally everywhere so we want to change the color so we'll just have is expanded is colors dot green basically our objective whenever we use animated XYZ widget is we want to change the value from one stationary value to a dynamic value you can do that however but the value should change and that's when animation will happen so that's the key over here that's the only thing to notice and then you can use your logic creative ID to make something so let's do the other things I'll restart I'll come over here and when I click you see it changes from blue to green and it also expands as I said animation and a complex animation especially is made up of several small animations in short so to figure out the entire animation just break the animation into several different components and work on that now the Border radius so vlab is expanded so if it's expanded is true then I want 30 otherwise 10 is enough now if I come over here Yep this also changes that looks good now over here I also want to change the icon I want to change it to a tick mark icon correct it becomes a tick mark so I can just do is expanded if it is expanded then I want icons dot tick if that's there no icons dot check should be there yep so if you have icons dot check and is expanded is there now it is giving us an error because we are using Dynamic values over here Dynamic values cannot be constant so let's remove that and there we go now if we come back Yep this changes perfect so after doing this if we come back over here and click over here you see this works now what we want to do is when we come over here let's go and when we click on the animation the text should also appear and the icon should also be there right now we don't have any text in our app except the app bar obviously so how can we do that well first of all we'll have to convert or we have to wrap this icon with a row widget right because we want two elements in one single line so we can put a row over here that's good now if we do this much you see the icon is over here now what I want to do is just put a text wire which says added to cart right and we'll just put in some Styles so let's say textile the font size is 16 the font weight is font weight dot bold and let's say the color is also specified so we say colors.white otherwise it will become black I guess and that probably wouldn't be good but anyways here we have added to cart now the problem here is when I click over here it works fine but when I don't click away I have it in this state added shows up I don't want that initially only my icon is showing but when I click on it the text shows up how can I figure that out so to figure that out we can use a very simple logic what we can say is if is expanded is true so if it is true only then should you show the icon otherwise don't show it to me so right now we don't see the text but when I click on it the text is seen now the problem we face with this is since we are in a row the icon shifts right in the start of the row we want it in the center so what can we do well we can do main access alignment Dot Center correct but if I restart it is in the center that's good but when I click on it both of them are in the center according to my animation example one is in the left and one is in the right so I cannot use Center what else can I use well I can use space evenly when I use space evenly in the beginning it will be right in the center and after that they'll be apart from each other they won't be congested together or staying together so yeah we are done with this animation it was a little bit tricky but quite easy once we figure out all the components that are needed in our animation just break it down into small steps and you'll be able to do it so if we come back over here we just had to use an animated container to do all the tasks there's still more you can do over here one thing you can do is wrap this text with another widget which is animated opacity animated opacity and it is just like the container opacity exists animated opacity just animates the opacity widget so if we just have opacity paths to it we'll just say is expanded is true then we want one otherwise 0 that means when the button is clicked on I want the text to display completely otherwise I don't want to display it at all then we have duration and the duration can be let's say milliseconds of 1500 just so that we can see it live okay so let's make it happen and restart so if we come over here yep you won't see any difference but yeah animated opacity is one of the widgets you can use now to get a list of these animated XYZ widgets what you can do is just go into the implementation of either animated opacity or this animated container and you'll see that the extend implicitly animated widget okay and when you search about this implicitly animated widget flutter Docs you'll come over here and see that these are the commonly implicitly animated widgets and these are the lists we have tween animation Builder which we are going to take a look at in our next example then we have animated align animated container animated default textile and so many more so I recommend you to play around with all of these widgets so that you get a feel of them and you understand how they work and another thing is just play around with these scores all right once you get a good understanding of them they're quite cool and can give you different user experience in your app so try it on your own I'm just going to remove this animated opacity widget because it's not really necessary and just restart so we have the shopping cart button animation done and you can just open the terminal and run flutter run Dash D Chrome dash dash release if you run this command it will run on Chrome on release mode that's what you want because in release mode these errors won't appear you cannot run iPhone simulators on release mode that is why I'm not able to show it to you on iPhone but you can on web so go ahead take a look run this command and see if you get this error so the demo is loaded and if you see the error just goes away so now that we are done with this I'm just going to close it and we're going to move to our last example of implicit example which is the animated tween animation Builder example so yeah let's go ahead and test this out so this is the next app that we are going to work on this is the animation that we are going to work on and let's just restart it to see it you see there's just a circle and it's glow and whenever we restart the circle goes from small to big and it's blur or whatever you can say it's glow starts to increase along with the circle as well so this is animation as well and this is what we're going to animate so let's get into the code so again the first thing we need to do over here is just copy this go to the main dot dot file and paste it over here okay also if you don't like warnings just get rid of these Imports and we're good to go so this is what we are going to start with okay we have a circle and a blur radius how do we do this well we have a rabba then we have in the center a container with a size which is 200 a constant value we are not animating at all then we have the height which is also 200 okay and then in the decoration we are putting in both shape dot Circle if we remove this it will become a square but what we want is a circle and the color should be blue the Box Shadow should be there and the Box Shadow is only one color you can add more colors if you like so let's go ahead with colors dot red and you see we are getting this kind of color if you are interested in it but I like only one color which is blue with an opacity of 0.5 so it becomes less prominent then we have a blur radius and a spread radius spread radius is like how much it is spread throughout this container or throughout the screen so we are doing size divided by two if we do do just size it will be a lot that's why size divided by 2 which is 100 because 200 divided by 2 and the blur radius so if we don't blur we don't get this kind of effect it will become much more prominent like this that's why we're using blur radius so that we blur it and this is the Box Shadow property inside of which we can use it it accepts a list of box Shadows so this is a wrap till now and we need to animate this how do we animate now well let's watch the demo to understand what we're doing well we're just going from a small circle to a big circle so can we use an animated container over here yeah sure we can use an animated container but we want to change the size right and we want to do that every time the app starts it's not on a click of a button or anything like that earlier when we used animated container there was a button which when pressed would trigger something and would you know change the color or your change the width color icon and add text but over here when we just restart the app we want that glow effect to be there you see just the app starts and the size increases so animated container wouldn't be a good option here because how do we start from zero and take it to 200 could we use energy state for that let's go ahead and try it so we have converted it to a stateful widget earlier the size is zero then in the nth state I'm saying hey the size needs to be let's say 200 okay and this is in final this is double and this is animated container then we will pass in a duration which is duration seconds 500. cool let's do it so if we start nothing really happens why well that's because in its state runs before the build function so you're saying hey size 0 and then you're saying size is 200 and then the build function builds because of that the size is already 200 you're not changing from one value to another value you're just keeping the size constant over here now you might ask can we do such State aware if we just do such state that should work right so if we try restarting this doesn't work why well that's because in its state function runs before build function doesn't it if it runs before build function what's happening is size is zero wear size becomes 200 and then the build function runs so the width and the height is initially also 200 you're not changing from one value to another value because of which animation doesn't happen but that's how animated container works right it works on a very simple concept you animate a widget property from its current value to another value which can be called as a Target value and the animation will keep running until that Target value is reached that's why this doesn't work it thinks of size as a constant 200 even though it is not a constant but over here in a build function it doesn't really change so for animated container to work we would need a button but no we don't have a button here so this idea doesn't work so let's remove these things so what should we do instead well for this purpose we have another widget that we can use and also let's convert the state full to a stateless widget because in this thing we don't really need a stateful widget we also don't need this animated container to be animated container we can shift back to container and we'll remove the duration so we don't have any evidence of Animation over here we are just out of Animation now we want to introduce animation because animated container did not work for us so what will we do well one approach we could take is just to wrap this container with something known as a tween animation Builder that also comes under implicit animation as I've already shown to you if we go back to the flutter dock surveyor to an animation Builder so what is the definition it's if twin animation Builder is a widget which animates any property expressed by a tween to a specified Target value this makes it sort of clear for us what twin animation Builder will do it animates any property that is expressed by something known as a tween so we'll get into what tween is to a specified Target value so it's kind of like animated container only animated container what was this doing it had a previous value then the value changed so it changed from the initial value to a Target value here it is animating any property expressed by a tween to a specified Target value so any property that is expressed by something known as a tween is being animated from one value to another value so let's get a practical example of doing animation Builder what I'm going to do is wrap this container with twin animation Builder so to do that first I'm going to wrap it with Builder so that I get this nice Builder argument here then I'll just change it to Twin animation Builder once we have tween animation Builder over here what we can do is pass the required arguments so the required arguments over here are tween and duration so we can pass in between then duration and we're done also this Builder has some arguments we'll fix that in some time but for now let's focus on tween and the orange so what exactly is a tween if you heard about this it says required tween object tween so what is this tween tween looks like something like a class right if we just go to its implementation and try to find here it is between of the type T so it has a generic type and it is called as tween if we go to the tween implementation you'll see it is a class it is a class that extends animatable so technically we just need to pass in a class over here and since it's not an abstract class or anything we can just instantiate it directly so we can just have to in like this and we're done but now it asks us for two optional arguments that are named so we have beginning and ending value so let's go ahead and pass them in we have begin so let's say begin is 0 and is 200. so we have written this out but what exactly does it mean a tween is a short way to say in between it is not a concept unique to flutter it is already present in animations Graphics flutter has just Incorporated that naming in its classes so two in refers to the frames or steps between two key points for example if you want to make an object move smoothly from point A to point B point a is the beginning point point B is the ending point you can create tween to show its gradual transition instead of jumping directly from point A to point B so in short a tween is a class in flutter that will help you to create smooth transition between values you specify a range of values by mentioning the beginning value the ending value and it will generate intermediate values within those beginning and ending values within that range so now that you have understood tween let's go go to the duration we already know what duration means it means how long is this animation going to last how long should it take for the tween to go from 0 to 200 so I can just pass in constant duration and the milliseconds will be let's say 1500 I want it to be 1.5 seconds long okay so within 1.5 seconds the tween has to go from a value of 0 to a value of 200. and tween will do it very smoothly so let's go to the Builder we have already seen some Builders already right we have seen stream Builder future Builder then there's this tween animation Builder so if you hover over this Builder it has different arguments just like stream Builder and future Builder have different arguments so yeah it it wants a function which we already have Builder is a function and it has build context classic Builder function then it will have an integer and then it will have a widget so let's type it in let's call the integer some kind of object and the child which was a widget as a widget okay so we have our error sorted out now the problem is just the size over here but what do these arguments mean we know what build context means but what is this integer and widget which is optional the integer over here is derived from the tween since this tween has zero and 200 pass to it if you hover over this it will say it is of the type tween of end and the beginning value is integer and the ending value is also integer earlier when we did not put anything the tween had object and object now since we passed in integer values now it is of the type integer if I pass in colors for example colors dot gray and colors dot White then this will become tween of color and this object will be color so this object's return data type is based on the screen what you pass to this tween so we'll come back to our normal values we are using 0 and 200 where because we want to animate this container right we want this container to go from 0 to 200 it should be nothing on the screen to something big on the screen so we've mentioned the starting and ending values over here so now we have an understanding of what this object is it is an integer so we know this object is of the type end but what value does this object contain to understand that let's understand how twin animation Builder works so you specified the T twin over here it contains of a beginning and ending value and what tween is doing is it is constantly moving from 0 to 200 right so it goes to 10 let's say 15 20 25 27 whatever and it is doing that smoothly so this build a function is called repeatedly during the animation with each call it receives the current value of the twin so what current value is the tween on while moving from 0 to 200 because if it moves from 0 to 200 and if it is doing that smoothly it is going over some values right that is the value the object contains it contains the current value interpolated by the tween and finally there's a widget which is optional what is this widget we are going to come back to this after a point first let's get our app working since we are already familiar with what object does it shouldn't be too difficult for us we already know object contains the values that tween interpolates between so object is essentially the size variable that we need over here right because if the size is 0 the container is not displayed if the size is 200 the container will be quite big and because of that will see your circle and the size variable interpolates between those values very smoothly so we'll get the animation we require but now we get an error we say the argument type end can't be assigned to the parameter type double and the reason for that is width and height require double values even blur radius and spread radius and here the twin is integer because of that it gives us a problem so we can fix that in two ways first one is to make the 0.0 and 200.0 because of that it becomes a double or we can just say 2 in of double like this so if we just pass and double these integers will be treated as double values so I prefer this way better and also one thing that you might not have noticed if you hover over tween animation Builder it is also of the type double since it is of the type double the Builder function also has a double value in the parameters okay now if we restart the app there we go our animation is now working if I again restart it is working just to recap why does this work we have specified a tween that goes from a 0 to 200 if it was 100 instead we would have a circle that has some size in the start it has a height and width of 100 but since we have type 0 here it starts from absolutely nothing to something right then we have a duration how long is the duration or the animation going to last 1500 milliseconds or 1.5 seconds then we have a builder which contains the current build context then we have the size variable that is the current value of the tween and then we have the widget we need to discuss more about this widget then we are returning a container passing in the width and height of the size and the spread and blur radius of this size so this is how it works again to remind you animated container did not work because we had to go from an initial value of 0 to an ending value of 200 and that had to be done without a click of any button without any trigger it had to happen as soon as the app loaded let's talk more about widget what is this widget well this widget is basically now let's talk more about this widget what is this widget so if you just minimize this container and put a comma after the Builder in Twin animation Builder you'll notice there's a property of widget which is optional called child so we can pass this child over here and this child is what the widget is if this child has a value the widget has a value if this child does not have a value widget is null so we can close this we go to the Builder function and we try to inspect in Twin animation Builder if what I'm saying is correct or not so we have final widget underscore child and this is a stateful widget as you can see over here at the top it extends implicitly animated widget and implicitly animated which at extends stateful widget so indirectly twin animation Builder is a stateful widget and because of that it also has create State function aware so if we go down and we see return widget.builder so it is returning the Builder function for us we it passes in the build context it passes in current tween dot evaluate which gives us the current value of the tween and widget.child so build a function has those three values only right belt context the current value of the animation and widget so this widget is ultimately the child that we get over here this child that I passed in a way up now as this child present over here this child is present because as I said the Builder function will get called as and when the value of the size changes whenever the tween is animating between two values and the size changes from one value to another value Builder is called repeatedly if this Builder is called repeatedly certain elements of this container will also get called repeatedly even those elements that have nothing to do with the size variable nothing to do with the value that is changing over here so why do we want to unnecessarily rebuild all of those things and that's why we have the child argument in this child argument you can pass in things that are not animating but you want to display or if you want to read it over here it says the same thing that I said if a builder callbacks return value contains a sub tree that does not depend on the animation so that means whatever value that we are returning over here let's say some part of the value does not depend on the size then it is more efficient to build that subtree once instead of rebuilding it on every animation tick that means instead of passing the child widget aware just pass it over here so that it builds once instead of rebuilding it every single time so let's say in our child we had a constant text which said hello world okay and what I want to do is display it in the container over here somewhere over here how can I do that well for that I can just present a child to The Container let's pass it in not in the decoration container and if I just type constant text hello world like this it will be inefficient why you won't be able to see the difference okay there's no supportable difference but it is definitely inefficient because this Builder function will be called many times as a result of which this text will be created multiple times even though this text does not depend on the size variable it has nothing to do with the size even then it is getting rebuilt again and again so instead of doing that what we've done and what we'll do is put the child over here to the and to in animation Builder and then we'll access this child that we have passed to the tween animation Builder using this widget property so we'll just pass the widget here like this save it and our app becomes more efficient as I said no portable difference but instead of the text being created multiple times when the Builder is run the text is only created once and then it is stored in the variable widget which is used over here so this becomes much more efficient for us so this is something you can experiment in our example we didn't really need this so let's remove it save it and we're good to go you can also specify the curve again in the tween animation Builder and it's the same thing you can pass curves or whatever curve you want to pass in you can do that so we are done with implicit examples now just to recap what implicit animations were implicit animations are animations that run or are triggered when the property inside of a widget changes and then we saw three examples for it we add animated color palette we add animate and shopping cart button and then the animated you can say pulsating Circle but we made use of twin animation builder in there in two of the examples we used animated container and other animated XYZ widgets we saw over here we sought tween animation Builder the difference between animation Builder and animated container or animated opacity those widgets was animated container could only animate the properties of a container widget animated opacity could animate only the properties of opacity widget tween animation Builder could animate property of any widget usually an animated container you would have to set a trigger point so that the animation Works smoothly over here in Twin animation Builder you did not have to put any trigger for it to work so twin animation Builder is more flexible and animated container is less flexible but animated container is very easy to use and twin animation Builder is maybe easy to use so that was the difference between tween animation Builder animated container animated opacity and all about implicit animations now let's close this and get to explicit animations so what exactly are explicit animations explicit animations are the type of animations where you explicitly tell flutter that hey I want to animate in implicit animations that was in the case in implicit animations you just change the value of a property and the animation occurred but in explicit animations you go out of your way to do extra setup extra configuration and make the animation happen in explicit animations the animation doesn't happen until you explicitly tell the animation to happen in implicit animations that was in the case we didn't have control over our animations and implicit example an explicit example we have the control over our animation so we can tell our animations when to happen and when not to happen so if you go to the explicit examples folder you'll see three files away list animation loading animation and login animation these are the examples we're going to work on all three of these are a bit different from each other but apply the same concept of explicit animation the first one we are going to take a look at is login animation so I'm just going to copy this put it in the main.dot file so that you know we are able to see our animation and I'm going to restart my app so there's no animation of any software if I just restart you can see there's absolutely nothing happening in this file or in this code now what I want it to happen and how it should animate looks something like this so if I just start this recording you'll be able to see the change so this is a sort of Animation we want to work on and I have a screen recording so that we can continuously refer to this and understand what we are doing and why we are doing it so if I play it once again and this time we are playing so that we can break down the recording and understand what animations are happening so if I play it at first there's absolutely nothing so if for a second you notice and go back there's absolutely nothing on the screen and then slowly a flutter logo starts to appear and then after that or not after that but shortly then we have our two text Fields coming in from the top left direction to the center of our app so these are the two animations that evidently appear in front of us first one this logo goes from being invisible to visible and this text fields and this button so the button is also coming from the left hand side all right so these three things coming from the top left to the center of the screen and another thing you might or might not have noticed is the scale of this text field if you just see there's a little difference between these text Fields because they are occupying a little space but then if I just start it again the size of the text field increases the Gap also increases and again if we play The Gap increases even further because the text Field's height is also increasing same goes for button if you just see the button it's so small over here but at the end it is super big so there are three things happening over here the visibility change we can do that using opacity we've already seen that with animated opacity widget in implicit animations then we have the slide happening we can do that somewhere and then the scale increases so these are the three terms you need to keep in mind and yes all set for explicit animations for this particular example so let's close this let's go to our code and let's figure out how we need to do this so to do explicit animations you need to convert stateless widget to a stateful widget and the reason we need to convert it to a stateful widget is because we want to make use of nth state so NH state is required because whenever our app starts we want the animation to occur and init state will help us in that because in its state is called before the build function in implicit animations it didn't work but here it will work so the first thing we need to work on is the visibility part which was the opacity so for that we need to create a variable that will hold the value of the opacity and it's not going to be like a normal double value or something it's not going to be like opacity is equal to 1 or something it's going to be of the type known as animation all right because only then will we have access to the status of the animation so if the if the animation is completed if the animation is still ongoing animation is going to help us with that and this requires a generic type you can or cannot pass it I'm going to pass the value as double otherwise it will assume it as Dynamic and I don't like putting in Dynamic when I know what the value is going to be it is going to be double and then I'm going to name it opacity okay and I've defined it late because the opacity value is going to come from here and it cannot be as simple as putting in one over here because it's of the type integer or 1.0 you cannot put it because it's of the type double it needs a value of Animation double and this animation thing is an abstract class so you cannot instantiate it so what is the value opacity is going to take opacity is going to take the value of a twin now you might say hey animation isn't a tween right and you're correct it's in order to in but we'll see how to make it work so in tween we are going to press a beginning value so in the beginning our animation or our flutter logo isn't seen so it's going to be 0 and at the end it is going to be 1 right because it's completely visible it's going from completely invisible to completely visible that's why it's going to be beginning from 0 and end will be one and now we all said we have a tween but now we want a value of animation and that's where we will call Dot animate property of arduin and tween has a lot of properties over here but the one we are interested in is animate because it will give us animation in teacher okay and it is giving us animation integer because we have passed in 0 and 1. again if we just do tween of double it will solve all of our issues so when we call animate it will start animating between these two values so opacity will go from 0 to 1 and we are calling dot animate because of which it will animate simple now what do we put in parent parent also requires a value of Animation double we need to pass something known as an animation controller over here and what is animation controller as the name suggests animation controller it is a controller that will basically control your animation so it will allow you to pause play stop repeat whatever you want to do with your animation and it will also specify the audition for which your animation is going to last and that's the big benefit of using explicit animations right it will give you complete control over your animation so let's go ahead and create an animation controller now so to create a controller again we are going to follow the late thing and we're going to have late animation controller let's call it controller and here before we Define opacity we'll Define the controller's value so we have controller equal to animation controller and we can create a class out of this right because it is a class it's not an abstract class so once you create animation controller it asks you for something known as vsync vsync is the ticker provider for the current context it can be changed by calling resync it is required and must not be null C ticker provider for advice on obtaining a ticker provider so vsync doesn't really tell us what a ticker provider is it just tells us that hey we need a ticker provider to be passed in a way so what is a ticker provider to answer that we must understand why animation controller needs vsync in the first place so the job of Animation controller is to control our animations and to control animations animation controller has to keep track of flutter's frames so a ticker will allow animation controller to do that a ticker basically keeps track of flutter's frames and allows the controller to follow that ticker and animate through it within the specified duration so if I put in a duration of 1.5 seconds in my animation controller the ticker provider will keep track of flutter's frames and allow that animation to happen within those 1.5 seconds okay so that's what a ticker provider does it will give you the ability to keep track of the flutters frame rendering and will allow the controller to follow that ticker and animate through it so now how do I get this vsync ticker provider value so for that it's recommended to use this value but this also gives us an error because this will give us access to the current class we are in and the current class we are in is login screen animation state so what do we do instead well we can just do with single ticker provider State mix and once we do that we're using a mixing in our class and once we have access to our mixin we can use this because this is now of the type single ticker provider State mix in as well that's how mixings work right so now you can just pass in this and you're able to use your controller now I can take this controller and pass it to dot animate and there we have it our opacity is now done so just to recap the first thing that is usually done and I did it the opposite way so that we understand why animation controller is needed is animation controller is created and controller is equal to animation controller then we need a vsync value and whenever you need a vsync value you can just put with single ticker provider State mix in but yeah sometimes a single ticker is not enough you need multiple stickers so in that case you can always use sticker provider State mix in which will allow you to create multiple tickers if that makes sense to you but for our login screen animation one ticker is enough so we're going to use with single Tech up provider State mixer then we create late animation double opacity which is equal to Tween double so we create a tween because in the start the visibility is not going to be there and at the end the visibility is going to be 1 completely visible because that's how opacity works right the values are 0 to 1. and then we animate between those tweens also what I like to do is whenever I create an animation of some sort I like to suffix it with animation so I can just write this as opacity animation and then I can use it but the other problem here is if we have somewhat of a complex example or somewhat of a complex animation to do then opacity animation is not very descriptive so you can make this more descriptive Maybe by using better variable names like logo fade animation and we can just put that put that in sorry awesome now that we have this do we expect the logo to animate not really why because in our UI we have not made any changes we have our variables and all of them are signed that's good no doubt about that but our flutter logo is still a constant size of 100 we have not told it to animate or anything so for it to happen we have to wrap a flutter logo or whatever widget you're on just wrap it with another widget and that is known as a fade transition widget why are we using fade transition widget because fade transition widget is having a required argument of Animation double opacity we are not going to use x animated XYZ widgets that we saw animated opacity for example we cannot use that because it requires opacity which has a required double value what we need is XYZ transition widget which will allow us to pass in animation widgets like this so we can just pass in like fade transition and then we have opacity and it requires an animation double value so we can just pass in logo fade animation aware and we're good to go because logo fader animation is of the type animation double and we're using fade transition because we need access to opacity right we want it to go from completely invisible to completely visible and fade transition allows that so if I started nothing happens but there is one change a flutter logo is not appearing here why because we have set the tween to zero so since we've set the value to a zero the logo is not seen the opacity is zero that means our animation isn't working and the animation isn't working because I want you to remember one thing explicit animations don't work until you explicitly tell them to work so you need to explicitly go ahead and tell your controller dot forward what this will do is start animating it will start animating in the right direction from 0 to 1 as I said controller allows us to control our entire animation if it goes forward if it goes in reverse if it stops if it pauses whatever happening is because of this controller and now if I restart there is no animation and that's because we haven't passed in the duration argument it is null how long is our animation going to last so we are just going to have duration and then I'm going to pass in seconds let's say 1.5 okay milliseconds 1500 there we go and we can also put constant over here Luxor now if I restart there we have our fading animation that looks good so I hope you understood the animation till here if not I'm just going to take a quick recap of what we have done because it might be a little too much to process and after that we'll get to the sliding and scaling animations that we have to do on these text fields and the button so if you've understood just skip through and if you've not just watch it again so we create an animation controller to create an animation controller we need a single ticker provided State mix in after that we just create init State we have a controller which is set to animation controller vsync is this this refers to this class and since it is having the mix-in of single ticker provider State mix in it accepts the value of techup provider then we have a duration argument and here it is required to pass in a duration so how long is your animation going to last it is going to last for 1.5 seconds or 1500 milliseconds same thing so now that we have access to a controller what we need to do is create another variable for logo fading so we just create late animation double logo fade animation and Logo fade animation is equal to Twin of double where the beginning value is 0 and ending value is 1 why because the logo fading happens from being completely invisible to completely visible and then we call Dot animate property on it or method on it which gives us access to animation double and it requires a parent the parent is the animation controller because animation controller basically extends animation double or any sort of animation and then we have to explicitly tell controller dot forward otherwise the controller or animation won't run then we also wrap our flutter logo with a fade transition widget if you want to perform opacity operations like from going from completely invisible to being visible that's what fade transition does here then we have opacity which is of the type animation double and logo for your animation is exactly that type which is why we used feed transition widget if we wanted something else we would use some other form of XYZ transition widget not fade transition and we are not using animated XYZ widgets because these take the type of let's say we have animated opacity this takes a type of double opacity not animation double opacity so it wouldn't work for us animated XYZ widgets are only used in implicit animations and XYZ transition widgets I use whenever you want to have explicit animations so the next thing we are going to work on is the slide so for slide we are going to have late animation slide animation let's call that and here I've not mentioned the type because I want you to think what the type is going to be and how this animation is going to happen many a times you won't know how to perform a single animation and in this case I don't know how to perform this sliding animation it goes from being invisible in the left side to coming on the screen and being in the center how will I do that so when you don't know what is the return type going to be you can just apply one method just wrap whatever widget you want to animate in this case I want column why column because the entire column username password and login buttons were animating right so I'll just wrap this entire column with a particular widget not padding because padding doesn't really do anything for us and I'm just going to wrap this with another widget which is known as what I don't know what kind of widget it is so I can just pass in a transition widget because I know at the end of the day this is going to be some form of XYZ transition widget so I can just scroll down and try to find a particular widget about it fade transition not really fade transition is related to opacity size transition size transition animates its own size and clips and aligns its child we are not really looking to animate our own size we are looking forward to making the entire widget slide it goes from one position to another then we have some other widgets let's see then we have scale transition it's like how zoomed in your widget is going to be so it's about that so we might use it but not for sliding and then we have the slide transition widget itself the slide transition widget animates the position of a widget relative to its normal position it animates the position of a widget compared to how the normal position is going to be and that's exactly what we want we want it to go from the left hand top side to the normal position it is in so I can just use the slide transition widget so this is a technique I often use whenever I want to know what type of Animation it is going to be and how I'm going to do this if there is a particular XYZ transition widget for it I'm just going to use that so for slide transition you can see it requires an animation offset of position it is quite similar to fade transition right fade transition required animation double opacity now it requires animation offset position so I'm just going to have animation offset away and slide animation is going to have similar stuff it is going to have slider animation tween and the beginning value that we are going to put in between is of the type offset now what is an offset offset is basically like a graph if you just think of it in terms of a graph let's say this is the entire graph that we have this is going to be negative one this is going to be 0. 0 is going to be the normal position of our widget and this is going to be one all right so offset DX is like mentioning the X Direction and offset d y is mentioning the vertical Direction so you're just mentioning the beginning of the slide in the beginning of the slide I want it to come from here right so what is this going to be so if this is the center let's say to go here we have negative 1 and to go up we love one right so our X is negative 1 so you can just pass in negative 1 and Y is 1. you see negative 1 and this is 1 and this is negative 1. so animation is going to start from here then we have the ending value now in the ending value where do we want it to be we want it to be in the center or wherever the normal position is so the normal position is going to be zero as I said so we are just going to have offset dot 0 all right and then we can call the dot animate property on it pass in the same controller a controller can be the parent of multiple animations here we don't have to worry about that so we have a constant here and we're good to go now we can just take the slide animation and put that in the position all right that's cool now if I restart see our animation is coming from the left hand bottom side why is that the case that's the case because let me just put a comma here that's the case because in the beginning we have mentioned negative 1 as the X so it started from here that's good but one is going in the bottom Direction it shouldn't go in the bottom Direction it should go in the upper direction right so you can just pass in negative one over here and now you see it is coming from the left hand side so in our case negative 1 is the Y component at the top and this is positive one so whenever you pass in negative 1 in The X you'll just go over here and negative 1 in the Y you'll go up and if you pass in 1 and negative 1 you were at 1 then you went negative 1 which is at the top and then you come back to your original position so you can play around with these offsets and you'll get a better understanding of it but here's the graph for it in the X Direction you have negative one and one and the values you can take between them then at the top this is negative 1 and this is positive one and this is for our case so this is why whenever we do negative 1 and negative 1 this comes in from here perfect but now you might notice that hey your animation that you showed does not have that right if we just see it didn't have this particular kind of Animation both the animations look quite different and that is because of the Curve in our animation controller we don't have the property to define a curve so where do we Define it to Define it you need to wrap your particular controller with something known as a curved animation curved animation also extends animation because of which you're able to pass it to animate and curved animation requires a parent and parent is also of the type animation double so you can just pass in a controller now so the parent of this curved animation is controller and this curved animation is used so that you can specify a curve that's how simple it is you just pass in a curve and we know what the curves are we can just pass in curves dot ease I restart the app and there you see it looks much in sync with what we already have so if you just specify a controller wire that's fine but it will take a default curve when you pass in curved animation you pass in a controller obviously but you also mention your curve okay so you can do that now it looks much in sync with what we had the last thing that we need to work on in this example is the scale animation so as I said whenever you look at this animation the text Fields go from looking small to big and that's there because of the scale animation so this is quite simple we need to use scale transition widget that we have already looked taken a look at so I request you to pause the video and try it on your own and see if you're able to do it let me know if you're able to do it in the comments below so to do it first of all let's just go ahead in our column wrap it with a widget and it's going to be scale transition scale transition requires the scale which is of the type animation double so we need to create a variable at the top which is late animation double and then we are going to name this let's say scale animation only you can improve the naming in both of these cases but for now this works fine for me scale animation is equal to Tween and how is our scale going to look like well what I want is in the beginning even the opacity is zero so that time my scale can also be zero so all my text fields and buttons are almost non-visible then as the opacity increases the scale will also increase so I want both of them to be in sync with each other so I can just copy those values so beginning at 0 ending at 1 I want my scale to be there and then I can just pass in animate controller and there we have it and here if you see we have an error and that's because again of the twin double issue we can fix that great now we can just copy the scale animation and put that in and then when you save it restart the app and you see our animation is now working it's not looking perfectly like this and that's again because of curve issue for example here again we'll have to wrap our scale animation with curved animation so we have controller then we have a curve which is curves dot ease and now if we save it and restart it looks just like our animation so you can get it by using curves and different forms of Curves you can make it look very different but what I like is this one better for some reason I like this one better than my example so I'm going to keep using this okay so yeah we are done with our animation and it looks quite good one thing to note here is that the scale transition is not between 0 to 1 in only opacity is between the value 0 and 1 for scale animation it can be five if you want that let's put that in as you can see we have our button over here looks quite weird then we have nine you can put that in it becomes much bigger you can put in a hundred and I don't think you'll be able to see it so there's no limit to our scale but one works fine because it perfectly matches what we want so we are done with the login animation now I just want to make sure that you understand what this animation double is I hope you've already understood technical ticker provide a state mix in animation controller to in and the animate property on it why we use curved animation all of those things but what about this animation double or animation offset I told you this animation class is used so that we know the status of our animation if the if the animation is completed if the animation is ongoing if the what exactly is the status of the animation so to know that you can just call multiple methods on something like logo fade animation or slide animation or scale animation like dot is completed is dismissed or value status you can use whatever you want and then you can also call Dot add listener property on it and then you can keep listening to whatever value changes happen over here so I can just say logo fade animation dot status okay I added a listener to this animation double value I can restart it open my terminal and you see animation status dot forward it keeps on forwarding the logo fade animations for like 90 times and then finally it says completed because the animation is completed and because of this ad listener I can do multiple things away like if logo fade animation Dot status or dot is completed so if the logo fade animation is completed I just want to reverse it so I can just use controller dot forward but instead of using forward I can just go reverse so whenever the logo fade animation completes it is reversing and you notice a strange thing happening over here so we have our animation happening and then it just stops happening for everything I just called controller.reverse in logo fade animation add listener and it reverse for everything and that's because all of these animations are animating through this controller they're all connected to a single controller so if the single controller starts all of the animation start if the single controller pauses all the animations pause if a single controller ends reverses whatever all of those animations have to follow that so to give you a diagram form this would be our animation controller and multiple animations are using animation controller to make their animations happen but whenever the animation controller says hey we need to pause then the entire thing all of those four processes pause nothing else happens this is why whenever we call controller.reverse in logo fade animation all of the controllers reverse so even logo fade animation reverses Slide the animation phase uh reverses and scale animation reverses so that's a very important concept I wanted to let you know and with that we can get rid of this controller we don't need that and we can get rid of login animation we're good now we have to go into the list animation so let's get started with list animation now so for list animation the first thing I want to do is just copy this list animation and put it over here okay so we have access to the list animation now and if you don't like warnings just remove these two things and be a good now what do we want the list animation to look like well first of all this is what the list animation looks like we have five list tiles you can see that over here we have five listiles in a list view Builder and then we have a floating action button for done like it's just there so that we can click it and the animation appears so it's a very simple list animation what do we want to animate it to well I want my animation to look something like this you see when I click on the button the animation starts and then I want all of these things to appear and when I click on the button again they all go again when I click on the button they appear and when I click on the button they go away and you see the pattern in which they're going away whenever I click the button one by one they start to appear and when I click on the button again one by one they go back so this is what I want and how can we make this happen well we are going to use explicit animations for it because whenever I click on the button our animation begins whenever I click on the button the animation goes back to its normal position and I think you'll be able to get it this time because we are not using anything different the only thing that is required is a proper logic in the scenario and this kind of Animation is known as staggered animation okay so let's go ahead first of all we'll just convert it to a stateful widget because we are going to use animation controller now and we're going to have with single ticker provider State mixer now I'm just going to have late animation controller I'll call this controller again and then I have my initi state make sure to initialize this otherwise you'll have error then we have controller equal to animation controller we think is this whenever we think this gives you error just add this line and we will have to pass in duration as well and the duration in this scenario let's put it seconds just five because we have like five list tiles right we have five listiles showing up over here so each of the list tile can take like one second if they want but I'm just going to put in five seconds over here the next thing we want is the staggered animation to happen so earlier we've seen that when we use slide animation all of those come in one by one so can we use slide animation let's go ahead and try it if I wrap my list Style with the widget known as slide transition I pass in position and this position requires an animation of offset so I can just copy this I have late animation offset let's call this slide animation I'll just copy this put it as slide animation equal to tween and what is my beginning offset going to be well in the beginning I want it to be in the left hand side so it's going to be negative 1 okay we have to pass an offset first so we have negative 1 and then in the y direction I don't want it to be up or down I just want it to be where it is if I can just pass the y direction as zero if we again come to our graph over here negative 1 is over here and 0 of y direction is also where so our animation is going to start from here and ending should be well offset.0 right so what's happening is we go from here this particular direction this particular place to this particular place so our animation is happening from year to year and then I just want to call Dot animate pass in the controller and don't forget controller dot forward right but if you do controller dot forward that means our animation just starts instantly I don't want the animation to start instantly which is why I've put a floating action button here here we are going to call controller dot forward okay and the position is going to be slide animation I know I've fastened the process here and we've fastened the process because we are already familiar with all of these stuff we have looked at it in the previous example the only difference here right now is controller dot forward the controller.forward is not in in its state because we don't want the animation to instantly occur we want it to occur only when the button is clicked on now if I restart and I click on the button you see all of the animations come together that's not what I want and this is why slide transition wouldn't work we need an improved logic so that all of these things come one by one so what can we do so my improved logic is that I just create separate animation offset for each of the list tiles over here for this one I'm going to create my own for this one I'm going to create my own animation offset even for this this and this so I'll create five animation offset and then I'll wrap the list Style with a slide transition widget and then I'll just use the appropriate animation offset that sounds like a good plan doesn't it but here's the problem what if my list increases from 5 to 10 from 5 to let's say 100 from 100 to a thousand thousand to two thousand now I can't animate all of those right I can't create an animation offset for each of them that sounds like a terrible plan so what I'm going to do instead is create a list of Animation offset okay so I'm just going to have late list of animation offset so this is going to be a list that contains animation offsets and I'm just going to name this animations again A Bad Name don't use this try something new and then just take animations now what I want to do is set animations equal to list dot generate will list dot generate what I'll be able to do is generate a list of five elements because there are five elements in our list view Builder and if you're a fan of Simplicity you can just take this item count at the top okay and make this as final so that it doesn't change and then you can just pass an item counter where item counterwear so as many list view Builder elements you have that many animation offset I want to create so I just pass in those many things and here I'll just return the same thing we would like we had in our animation offset as well right we had a tween that went from offset from beginning offset as negative one comma 0 to offset.0 that means it's normal position so we are going to use this tween over here for each of the elements okay for each of the animation offset and then we're going to call the animate property on it pass the controller or curved animation whatever you want to pass in awesome so what we've done over here is generated a list of five elements which returns a tween that starts from the left hand side and comes to its normal position okay now I can just take this animations wrap my list Style again with a slide transition and the position is going to be animations at index why am I doing art index because whenever I use animations at index I get access to the appropriate list right or the appropriate animation offset if you're creating element five elements over here then animations at zero which will be our first Element Animations at one which will be our second animations at third will be fourth element and animations at Fourth will be Fifth Element so that way we have access to the particular position and we have access to our particular animation offsite now we can just start it I click over here and our animation still appears together what is the problem here well the problem is we've created a list of Animation offset and we have made every list I'll have its own animation offset but there is nothing unique to our animation offset it's not the same instance but it's the same thing that we are passing in it has a beginning value of negative one zero it has an ending value of 0 and there's nothing unique between all of those animation offset there's no time delay put in between all of those animations and because of that all are appearing at the same time we need a way so that we can add an interval in between like a delay in between and when we do that each of the animation offset will become a bit different from each other and will behave more differently just to make sure we are on the same page I'm going to demonstrate what I'm talking about I'm just going to open the widget inspector I'm going to go down and you see we have a list view that's great and then each of our list tile now has a different slide transition widget attached to it right and when we go to the slide transition widget details tree you'll notice that we are having the same value for each of them there is no noticeable difference between all of them they are just different instances of the same thing that we are doing they all begin at zero they all have the same beginning value they all have the same ending value and there's no delay in all of them so we need to add that DeLay So how do we add that delay and to add that delay we introduce A New Concept which is interval so with interval you pass in a beginning value you pass in an ending value and it will delay it by that time for example if I just mention 0.5 over here 1 over here that means my animation will happen only from 50 to 100 so that means if the animation is like 5 seconds or 6 seconds long let's say the animation is six seconds long if we do it from 0.5 to 1 that means our animation will start from 3 seconds and will go up till 6 seconds so from 0 to 3 seconds it will not work that means it will stay stationary and from three seconds to 6 seconds it will animate so if we just go to the interval class in flutter Dev you can see a graph over here it's the same example that I gave you if there is a six seconds animation and it uses an interval from 0.25 to 0.75 that means from 0 to 0.25 it will not animate then from zero point to 0.75 it will animate and from 0.75 to 1 it won't animate so our animation will not work from 0 to 0.25 percent which is 0 seconds to 1.5 seconds because 25 percent of 6 seconds is 1.5 seconds then it will animate from 0.25 to 0.75 percent which is 1.5 seconds to 4.5 seconds and from 4.5 seconds to 6 seconds it won't work so in our case what do we want well what I want to do is get access to this index okay and multiply it with 0.2 why 0.2 because I have five elements all of them need to show up so I'll just do 1 divided by 5 which is 0.2 because like the maximum value it can take is one the number of elements you have is Phi so we multiply it by 1 divided by 5 which is 0.2 and if you just need to make this more Dynamic then you can just do item count one divided by item count all right and that works too so that's the logic we applied to get 0.2 because we have five elements then one divided by item count will be 0.2 so we are essentially multiplying by 0.2 and the reason we took this logic is because let's say we have five elements the first index will be 0 into something so it will be 0 so the interval will be 0 to 1. so it will complete its entire animation then it will be zero point 2 which is 1 into 0.2 so 0.21 then we have 0.4 and 1 then 0.6 and 1 then 0.8 and 1. that's why we have this kind of logic over here I hope you've understood it if not let me know in the comments and I'll help you with it so I'll just take this interval away because this requires a type of Animation double and interval is not an animation what we need to use instead is curved animation we'll pass in a controller and for the curve we can pass interval because interval is essentially extending a curve okay and it is curves dot linear but we can change that now that we have access to this we can just restart because the animations at index is there I can click on this and each of the element will start to appear one by one you see and that is happening only because of this interval and the logic we've used over here I'll just explain it again in case you didn't understand our index is initially 0 and 1 divided by item count will give us how much delay we want to put in so in between every list Style I want to put a delay of zero point two seconds so I can just type 0.2 second interval here if I just put 1 divided by item count it will just start from 0.2 all the time and that's not what I want if I just do this it's just static that means when I click over it it will pause for some time and everything will come together what makes this Dynamic is multiplying it with the index we are getting because index has a different value all the time if you have five elements the maximum index can be four and all of them will have a different value right so this line basically adds a 0.2 second interval between all the list tiles now you can restart again check over here and it would work now you can change the curve over here but I like this curve and it looks good now the next thing I want to do is if you see over here whenever I click the done button over here again all of the animations go but when I click over here the animations don't go so for that we can just use if condition so what we want to do essentially is if the animation is done and the user clicks on it again then I want to reverse it otherwise I'll just forward it so I have if controller dot is completed so if it is completed then I want controller dot reverse and if it is not completed then I want it to forward okay so I'll just come over here I'll click on the done button that looks good and when I click on it again it all goes away so you can see animation controller gives us access to control however our animation performs and interval helps us in adding delays and that's the thing that forms a staggered animation so we are done with the list animation I hope you understood this concept of staggered animations if not let me know in the comments and I'll be more than happy to help you out with it well now let's move to the last animation of explicit animation which is the loading animation and this is going to be pretty easy as compared to the list animation so let's dive into it so in the loading or radial progress animation what we are going to do is just copy this then go to the main.file put it over here and let's see what we have but here when we instantiate it we get an error because this widget requires two arguments from The Constructor one is the progress and one is the color so the progress shows how much of the progress is done in the indicator and the color is what color the indicator should be so for Progress I'm going to put in 0.65 which is 65 percent and the next thing we want is color so the color is going to be colors dot blue let's say not black blue then we save it restart the app and here we have our loading animation there's no loading as such a way up but we want to make it load how let's see a demo so how it should happen is whenever we click on this button this progress should show up so the style animates and even this number animates so if I click on it again you see 65 percent happens so this is what we want to animate all right so let's get started with it so the first thing we need is obviously a stateful widget so that we can create an animation controller also we need with the single ticker provider State mix in whenever you want to create an animation controller that's a must after that we are just going to have a late animation controller we're just defining a normal animation controller all right and then we'll create an NH State and here we're going to set the value for our controller so the controller is going to be animation controller vsync is going to be this already seen this before duration and here how long should our animation stay so the duration is going to be milliseconds and we can pass it thousand so that's one second that looks cool now the next thing we need is whenever the animation starts I just want it to go from 0 which is absolutely nothing to the value that we have passed to the progress right so if the progress is 0.65 I want our twin to go from 0 to 0.65 over here so we are going to create a late animation double and I'm just going to name this an animation so that I don't spend much time thinking about the name and then I'm going to say animation is equal to Twin again the same things we've seen again and again then we have the begin value zero but the ending value here is going to be widget dot progress because this is where we get our progress from right we get a progress from over here 0.65 so it will go from 0 to 0.65 and then we'll animate that path in the controller which is the animation controller now the problem is again the double value so we can just pass in 0.0 over here because widget.progress is always going to be a double no matter what you put in awesome so now that we have access to animation now let's understand how we will show the value so in our UI we have we are returning a scaffold where the Body Center stack we have a stack because we want to show a circular progress indicator and between that we want to show this text so we have our circular progress indicator over here and on top of that we have our text so it appears like the text is in middle but in reality they're stacked on top of each other and here I'm just doing widget.progress in 200 so that's 0.65 into 100 which is 65 percent so we see 65 percent return over here now let's again see the animation how we want it whenever we click over here so we can just go to The Floating Action button here we can just have con controller dot forward so if we have forward the animation will start from here but nothing happens as of now because our variable animation isn't connected to any part of the UI usually we have slide animation or slide transition fade transition all of those stuff but the transition widgets won't work over here and the reason for that is we want to animate this section so we want to animate this part and the text both of them and there's no widget that supports this which is why I use this example in the first example we saw the use of XYZ transition widget here we saw XYZ transition widget with interval but over here no XYZ widget can be used and interval is used for delay so that whatever we've learned till now wouldn't be applicable over here so what do we use instead none of the XYZ transition widgets are going to work for us and for this purpose we have another widget with us and what I'm going to do is just wrap the stack with that widget and that widget is going to be Builder but not normal Builder we're going to have animated Builder you remember the tween Builder we used in implicit animation animated Builder widget is kind of similar to Tween animation Builder if you remember in implicit animations we used tween animation Builder whenever some animated widget could not be used for example animated container could not be used animated opacity could not be used no animated XYZ widget could be used in explicit animations animated Builder is used whenever you don't have any transition widgets like slide transition doesn't work fade transition doesn't work that's when animated Builder is used so it requires two things the first one is an animation and the second one is a builder so we just pass an animation then we pass in Builder and in the Builder we have context and a widget and the widget you already know that's a child the thing that doesn't rebuild so as I said it's kind of similar to the tween animation Builder but this is for explicit animations because this requires a listenable so what is this listenable so listenable is a concept used to describe objects that can notify other parts of your code when they change or have important events that's what our animation does right the animation double is an object that notifies other parts of our code when they change or have important events that's how we know the animation is completed that's how we know animation is dismissed that's how we know the status of the entire animation so does that mean I can just pass animation over here yeah you can't because behind the scenes if you see animation is an abstract class that extends listenable so we can definitely pass data animation in can we pass the controller yeah you can because animation controller also extends animation and animation extends listenable so yeah you can do that but we want to and we have we have to pass animation over here because we have a tween because that's what we want to animate right so it's kind of similar to Tween animation Builder because in tween animation Builder you just pass in between and an animated Builder you pass in between dot animate and the whole widget updating process is the same if you have any widget that doesn't depend on the value you can just use the child argument and animated Builder and whenever this animation changes Builder is triggered again that's the same flow that twin animation Builder also uses okay so I'm not diving into it now if I just restart you see nothing really happens it doesn't update because we have passed the value as widget.progress widget.progress is a double value it is a static double value because this animation that we see this animation double gives us the entire status of the animation right so it will also know where the animation is what its value is where it has reached in the animation and where it has reached is dependent on this tween right so if we are at 40 it will be stored in animation double that's what the double value is so we can just use animation.value here and even over here we are not going to have widget.progress you're going to have animation.value into 100 and now if we save it you see we're starting from 0 and when I click over here we have 65 percent if I do it again I'll click over here and we have 65 percent that looks good right so we are done with the loading animation as well and this marks the end of explicit animations as well so in explicit animations we learned about single ticker provide a state mix and what it is why it's necessary animation controller animation class then about tweens animating then about controller and what all stuff it can do then the XYZ transition widget there are a lot of widgets that are transition widgets you can look into all of them we have fade transition slide transition scale transition we also had align transition many more are there then we went into list animation to try out staggered animations and we use the concept of interval rest of the things were pretty same we just had to apply a bit of logic and we were able to get our style animations up and working after that we went to the Loading animation where we learned about animated Builder and it is similar to Tween animation Builder so in general implicit animations are animations that run or are triggered when the property inside of a widget changes or when when the value of a property inside the widget changes and explicit animations are animations that don't animate until we explicitly tell them to animate and that's what controller.forward did it explicitly said to the animation that hey you need to start running also to find a list of animated widgets that are XYZ transition widgets you can just visit this website I'll mention in the description below and you can see we have fade transition slide transition size transition scale transition rotation transition all of them so you can look at take a look at them and maybe try using them in your own applications but yeah I'll mention the link in the description below go and check it out now you might be saying that hey how do I decide if I need to use implicit animations or explicit animations I'll just say that if you think it can be done via implicit animations great just go ahead and use them you don't have to set up like a controller you don't have to set up all of these things but if you require more control over your animations or you think it is not possible via implicit animations then definitely you'll have to use explicit animations there's no hard and fast rule that hey you need to use this at this time this at that time you can use implicit animations or explicit animations whenever you want or you can just combine them and make one great animation so yeah let's get done with it we are done with implicit and explicit now let's dive into page route Builder animation that also requires the concept of explicit animations but we are going to focus more on the page route part of it okay so let's get started with Splash animation okay so as usual we are just going to take the splash animation we are going to go to the main.file and put it in the home and make sure to import Splash animation there we go and now if we restart the app and come over here this is what we have a blue dot nothing else but if we go to the code you'll see that we have a first screen and we also have another screen down here the first screen has a scaffold with a body of centered container with width and height of 100 and a circular blue thing over here in the second screen which is called the destination we have a stateless widget and here we are just returning a scaffold with the blue color and an app bar that says go back nothing else so what we want to do in this animation is go from Splash animation to destination and that's pretty easy right if we just wrap a container with a gesture detector widget we use on tap and if we do Navigator dot of context dot push material page route I'm not using named arguments or named routes in this case and then we'll have context and then we'll just return the destination that's the destination screen all right also put a constable here cool now if I restart nothing changes but when I click on this circle I go to a new page which is blue in color and has an app bar of go back and this works fine but what do I have to do to make it look different I want to add animations over here so that it looks completely different so let me show you a demo of that so this is the completed animation I'll just play the recording and you'll see it when I click on this blue button over here it should animate like this you see I'll just go back now and once again when I click on it you can see the animation this is what we want to animate to right now we only have this when I click over here I just shift the screen without any animation so let's add this animation will be cool so how and where do we start so to understand this we'll have to break the animation down once again what is happening in this animation if I start playing it the button is clicked on the blue thing that is there it's clicked on then it starts expanding and it takes the entire screen width okay after it has taken the entire screen height and width it goes to the new page and in the new page you see there's kind of like an fade animation if we just come back you see slowly it starts to appear so it's a mixture of two kind of animations the first one is on the current page we are on this is clicked on and it expands to the entire screen and the second animation is of the app bar the app bar fades in so let's get started we know how to make this happen right first we'll just convert our stateless to a stateful widget okay now I'll just pass in with single ticker provider State mix in then I'm going to use NH State I want to get access to my controllers so I'll have late animation controller controller and then we'll set controller equal to animation controller vsync is this and the duration for this can be 500 milliseconds so let's pass in milliseconds 500 looks good great now we have access to animation controller and now we just want a variable of Animation that when we click over here it just fills the entire screen how can we make this happen think about it for a minute or two pause the video and you'll be having a hint of what to use because we've already used this kind of stuff before so the thing we're going to use is scale animation okay you see it is just scaling up in size right it is of the normal size before and then it starts expanding and taking the entire screen size we also saw that in login animation I set the scale to like 100 and we weren't able to see it but since this is a blue color we'll be able to see it so now that we have created the controller I'm just going to create late animation double and I'm going to name this scale animation because that's what we need we need a scale animation so that this circle can expand and take the entire screen size we need to scale it up right and then we can just take scale animation and set it equal to let's say tween where the beginning value is something and the ending value is something so what will the beginning value be if we set it to 0 then the entire container will also become zero because we are using scale transition right so if we use 0 in the starting will not be able to see anything if we use one we'll be able to see the normal container and if the end is 10 that's great it will take the entire screen width and height and size I'm assuming if not we'll change the value then we can call Dot animate on it pass the controller to it and we're done but also we need to mark this as double perfect now I can just take the scale animation wrap our container with a widget like scale transition scale and we'll pass scale as scale animation cool now if I start we see a circle and when I click on it we again go back to the other screen no animation happens because controller dot forward wasn't called yet so we can just remove the on Tab and have controller dot forward I know I've rushed this part a little bit and that's because this is explicit animations I hope you are able to make this on your own because explicit animations you've gone through three examples and scale transition was used in one of them the thing we are concerned about is the page route Builder that we are going to take a look at in just a moment but let's see if we've figured out the explicit animation part of it now if I click over here you see we are done we have made this part of the animation happen now the next part of the animation is which is like after this is done the app bar starts to appear this app bar appears because we have transitioned to another widget so as soon as our animation over here gets completed we want to make sure that we move to another screen and for that we've already taken a look at it right we can just use the properties present on controller if we just have controller Dot add listener vehicle so if we use controller dot add listener or scale animation dot add listener both will do the same thing so you can use either of them let's shift back to controller doesn't make a difference and now we can just check over here if controller dot is animating is completed right if the controller is completed the entire animation of controller is completed that is 500 milliseconds have passed then we just want to navigate to another widget so we can just call Navigator dot off context dot push material page route Builder will be context and finally what is the widget we want to go to destination so we'll just put in constant destination perfect so now if I restart my app click over here you see I'm going to the new page it works our animation is now working that's great but the problem here is if I go back I'm welcome with a screen that is completely blue I don't want the blue screen I want my blue dot or my blue container which was this small back again the reason it is entirely blue is because we have scaled up our animation it is now at 10 so it is showing us a container which is fully blue we want to make sure that it resets its position it comes back to its normal position the scale transition is one again it shouldn't be 10 anymore and this should happen only when the animation is completed so that's why here I can just say controller dot reset right if I call controller.treset and restart my app you see I come over here I'm go back to the new page and when I click on the back arrow button I see this blue dot again but the problem with this approach is when I click over here you'll notice for a second that I again see a blue dot I don't want to see the blue dot at all it ruins the user experience you see so what I want to do to fix this is make sure that this entire animation controller's duration the entire 500 milliseconds is over the transition has happened and after that I reset it so for that purpose I'm going to introduce a timer over here and the timer is going to last for a duration of 500 milliseconds and then I call controller dot reset right so the controller is completed the animation is completed then we are transitioning to a new page and when we are transitioning to a new page I cannot change it back the controller cannot be reset because then we see a blue dot so I've just told it to wait for 500 millisecond the transition will complete and after that the controller can reset now if I restart click over here you see it works and when I go back I have a blue dot back again that looks good right so we've completed the explicit part of this animation the second part is the page route animation and we've not taken a look at that so we'll see the example video again and you'll understand what page route transition I'm talking about if I click over here and now if I click it back again you see the app bar and the entire screen starts fading in right it is almost non-visible at the start and it starts to appear slowly so this is the page route transition I'm talking about the entire screen just fading in so definitely we're going to use fade animation over here it is related to opacity and it's not just for this app bar it is there for the entire screen so if I just put a body of Center child text let's say hello world and but a constant over here I'll restart my app and come over here you see this app bar and this hello world text both should appear slowly both should have that fade animation attached to them not just the Abba and this is where pH transitions can help us now that we have a clear understanding of what we want to do in page transition we can understand how to do page transition so to do page transition first of all you need to remove this material page route or if you're using Cupertino page route remove Cupertino page route as well don't use either of them we are going to use something else so the thing we are going to use is Page route Builder as a fun fact page route Builder extends page route and material page route and Cupertino page route also extend page route but with page route build up you have access to more functions and features and properties so with page route I can put my own transition in with material page route and Cupertino page route that is in the case we cannot do that that's why we are using page route Builder and then in the page builder we get a function with some arguments so let's put that in we have context coming in we have animation coming in and we have something known as a secondary animation coming in we don't need to be concerned about these Arguments for page builder we look at them in another argument that we are going to use page builder has a simple task of determining what page is going to be returned so what is our destination page we are on Splash animation page what page do we want to go to and the page we want to go to is this page right over here which is conveniently called destination so we can just say return destination all right and this is also going to be a constant awesome now if I do this much and have my Splash animation yeah it works but there's no animation transition whatsoever if I go back you see it just exits the screen there is absolutely no animation or transition so now you need to figure out a way to return a transition and for that we have another property here which is the transitions Builder so we have transitions build here and it has four Arguments for us one is the build context second is the animation third is the secondary animation and fourth is the child so what are these things and what is this transition Builder and how is it different from page builder so let's first start with the difference between Page Builder and transition builder in Page Builder you just return a widget that you want to build so what is the page you want to transition to transition Builder is what transition you want to add while going to this page and for that it gives us access to a build context it gives us access to animation what is this animation this animation represents the progress of the transition from previous to current page so as the animation or as the page change is happening what is the progress in there how much of a transition has happened from previous to the current page secondary animation represents the progress of the transition of the previous route the previous route here means the one that was pushed off the screen so secondary animation is generally used when you have transitions where elements of the previous screen need to animate out and then finally this widget child is the widget that is returned from here what is the page builder returning that widget is going to be the child over here so we have figured out the destination as the page now what sort of Animation or transition do we want to apply well it's pretty simple I want an animation that looks like this you see in the beginning there's nothing and slowly it starts appearing so it's a fade transition so we can just return fade transition but what will our opacity be what will our child be right well our child is going to be the child the child that was returned away because this child is this destination so we essentially want to have the child as this destination right even when we have our scale transition over here the child is this container because that's what we want to animate the same happens over here destination page is what we want to animate so we are returning a fade transition with child Labs over here and what is the opacity going to be so the opacity should only be dependent on how much of the transition has already happened so if the transition is fully completed and by transition here I mean the transition from previous to the current page if that transition has already happened then I want to display the Abba and the entire screen otherwise I don't want to display the entire screen so our opacity is going to be this particular animation because this animation tells us what is the progress of the animation from the previous to the current page and that's exactly what the opacity should also be it should be zero if nothing is seen on the screen that means the transition has not started it should be 0.2 if we've completed 0.2 percent of the entire transition so we can just put animation and we're good to go now if I restart the app click over here you see we have our proper animation there and it looks great one thing to note over here is that the page builder only builds once the transition Builder however can get called many times and in transition Builder you can not only do Fade transition but other types of and transitions too for example if you want slight transition so if you want your page to pop up from here from the top Center how can you do that well this would require you to pass in position and position is animation offset how do I create animation offset so how can I get this animation offset this only gives me animation double right so how can we do it we can create our own tween and make that happen so I can just go ahead and create my own tween which is equal to Twin beginning value will be an offset and where do I want it to begin from from the center and from the top so my DX is going to be 0 because we wanted to start from here so I'm on zero position and I want y to go to negative 1. okay and let's put constant over here then the ending value what will the ending value be well offset.0 I just want to come back to my normal position great now that I have my tween I can just call Dot animate property on it now what will the parent over here be well the parent usually used to be animation controller but here we are not going to create animation controller and the reason for that is we already have access to an animation double which is this particular animation we can just take that in and put it over here and then we can pass the twin over here the slide transition should work so let's restart it click over here and you see that dropped in from top to bottom so the reason it worked was in between we just mentioned the beginning value negative 1 0 from somewhere from over here outside the screen coming back to the normal position and then we are animating using the animation object this animation object as I told before many times tells us the progress of the transition from previous to the current page so I'm just saying that hey just animate on the basis of this this is your parent widget or this is your parent object just take this and on the basis of that animate it for us and that's why this was pretty quick right if you just see this was pretty quick and of course if you don't like this you can wrap your widget with a curved animation as well so if you just put a curved animation pass the parent of this animation and the curve can be curved dot ease in out let's try this and let's restart the app click over here and you see this looks much better so you can play around with this and you'll have your perfect transition you can create your own tweens you can use your own curved animations you can make your own curves you can do whatever you want over here and that would work just fine in page route Builder there is other things you can change like transition the audition reverse transition duration transition duration is just like how long is the transition going to last reverse transition duration is when the screen is popped off the transition happens in Reverse right so how how long should that duration be and rest of the other things you can take a look at so this was page route Builder and many stuff that you can do inside of it the next thing I want to show you is how you can continuously use this page route build up for example you like a certain transition so much that you want to apply it to all screens of your app so if your app has like 20 screens you've made some transition and you want to use it to transition from one page to another in your entire app how will you do that will you keep on writing this page route Builder everywhere yeah you can do that but the problem with that is what if you start disliking that animation if you start disliking that animation and transition you'll have to go through your 20 screens change stuff everywhere and that's not an elegant solution so for that reason we can create our own route so what I'm going to do is go down here and I'm just going to have class my custom route transition and we can just extend that to page route Builder so if I do this and extend it it gives me an error and the error is there because we need a super argument so we can just create Constructor to call Super and we're good now I just want to implement all of my logic that I had implemented over here in this particular class and then I can keep using this my custom route transition everywhere so instead of requiring this argument from The Constructor I'm going to write it on my own so I'm just going to remove this off I'm going to put a colon here and I'm going to have my super argument like this also here we would require the route so what route are you transitioning to what page you want to go to so I would require that and rest of the things I can just Implement over here so by calling super I'm calling the parent class which is the page route Builder and then I want to pass in Page Builder argument you see by super I've called the page route Builder right and Page route Builder has a required argument of page builder I'll just copy that page builder from here to there so I just have this over here and there we go another thing that I need is this transition as well so I'll just take this transitions Builder the entire thing and I'll put it over here perfect also I need to create this route so I have final widget route so I'm just accepting a widget from The Constructor where I want to animate to and I'm just going to return this route now so instead of destination I'm just generalizing it that hey whatever you pass to the Constructor of my custom route transition I'm just going to go there and we have our custom transition class now I can just take this put it over here my custom route transition and I can pass in my widget which is destination also I'll put a const here I'll save this and when I do this it works the exact same way the only difference is that all of the logic that was present over here has been shifted to a separate class of its own and now I can reuse this class continuously and just to explain the code over here so what I'm doing over here is calling creating a class my custom route transition it extends page route Builder since we are extending it now we can use it in place of Base page route Builder so I have access to putting it over here then I asked for the destination route that we are going to from The Constructor and then I'm just calling super super refers to page route Builder only so I'm calling this class over here and passing the required arguments to it so the page builder should return the route that I'm getting from the Constructor the transitions Builder should transition like this the entire logic that we had written before and now I can reuse this my custom route transition again and again so I hope you understood this and I know this can be a bit tricky to understand but if you analyze a code on your own you'll be able to understand if not let me know in the comment section and I'll try my best to explain it again so now let's get started with custom painter so in custom painter the example that we're going to take a look at is this bouncing ball animation so what happens in this bouncing ball animation well in the starter code we just have a scaffold with a safe area widget and a column with main access alignment Dot N and here the comment says Needs ball so basically we are going to have a bouncing ball animation and the ball that we are going to create is using custom painter now you can create this ball using a container as well but I just wanted to demonstrate how you can create a ball by directly drawing on a canvas so this is just the starter code that we have we are going to basically make this entire animation from scratch so let's just take this bouncing ball animation put it on main.file import it let's remove the warnings save it come back to our file and there we go now how does the final animation look like so for that I'm just going to show you this video so it's a very simple video with this ball going up and down moving up and down that's all there is to this animation we need to make that how can we make that well first we'll start with creating a ball we want this blue circular ball to be present there now as I said you can use a container but I want to demonstrate how you can create a custom painter wall as well so first what is custom painter custom painter is a tool that allows us to directly write on the canvas it allows us to create any shape we want any graphic we want there are certain limitations when it comes to widgets and flutter certain widgets cannot create the shape you require so that's where custom painter can help you it will help you draw on the canvas directly so that you have a widget or you have a graphic that you like so how do we create custom painter to create a custom painter first you create a class as usual and let's just call this bouncing ball paint and whenever I am creating a custom painter I like to suffix it with painter so that I know that hey this is going to be a painter custom painter and then we can extend it with custom painter as simple as it gets not custom paint custom painter once we do that it asks us to put in some implementations the first one is custom painter dot paint and second one is custom painter dot should repay so for that just come over the class press command full stop create two missing overrides and it will do that for you the first one is the paint and second one is should repaint so in paint you are basically going to have the main part of your code what do you want to paint on the screen how will your design look like so canvas can help us there because we are directly going to write on the canvas right and then we have the size which tells us the size of the painter it tells us how much size is available to us so we can use that in our calculations as well the second one is should repaint should repaint basically tells that hey should this custom painter rebuild whenever a new value comes or a new instance of this bouncing ball painter is created and then usually it is return false but in our case it is going to be returned true it's usually return false because it is a computation heavy task because it will repaint on every frame so it will get new values and it will repaint the entire custom painter so usually it is return false because most of the times you don't have such tasks but whenever you have where you're getting new values all the time you return true and in our case we are going to get new values every single time because we are going to start an animation and to start an animation and we can't put any animation related code inside of this I mean you can put it but putting it inside of custom painter would not benefit you in any way so that's why we are going to have all our animation code set up in our bouncing ball animation and then we are going to pass the value to this bouncing ball painter using which we are going to make sure that this circle or this ball goes up and down so anyways we are here to create a ball so let's go ahead and create a ball and our ball is pretty simple all we need to do is create a circle and to create a circle canvas gives us methods for it and if we just do Canvas dot you see there are tons of methods you can use clip path clip RX clip correct draw Arc draw Atlas draw Circle that's what we want right we want to draw a circle so we'll just click on canvas dot raw Circle and it asks for three arguments the first one is offset second one is radius and the third one is paint what is all of this and why is it required to draw a circle well the first one is the center point so what should the center point of your circle be and for that it will require an offset right it will require the x and y coordinate of where you want to draw the circle so in our case we'll just create an instance of offset the x value should be size dot width divided by 2 so whatever size we have in custom painter I want that divided by two so that means I come to the center point right and in the y direction the value is going to be 0. because I just want it to be in the center right so in the Y it would not have any height so to show it to you in terms of graph let's say the x-axis is size dot width and the y-axis is size dot height all right so size dot width divided by 2 would mean it would come somewhere in the center and Y 0 means it will stay over here it won't go anywhere else I don't want it to give it a height or anything I just want it to be where it is over here in the center so size dot width divided by 2 and 0 then we need a radius so our radius is let's say 20 and then we want to give it something known as a paint what is this pane well paint is a class that if you instantiate you can get it so if I just do paint we have it but what does this pain do paint will determine what will be the color of the circle what will be the style of the circle meaning do you want it to be color filled or do you want only the stroke of the circle and it gives a bunch of other more methods that you can check so paint will determine basically the appearance of our Circle so what I'll do here is pane dot dot color which is equal to colors.blue that means the color of the paint is going to be colors.blue this is the same as doing final paint is equal to paint and not final we'll call this variable because now what I'm going to do is paint dot color is equal to colors.blue okay so doing this is the same as doing this this is just a shorthand syntax so yeah we've created a circle now we just want to display this custom painter how are we going to do that to display a custom painter what we need to do is first of all remove this comment and then have custom paint this is the object we will instantiate to display it on the screen because this is a widget custom painter isn't a widget so we have custom paint over here and now to custom paint we are going to pass a painter property which is bouncing ball painter and that's how you display a custom painter on the screen so now if I restart so you can see the ball is over here and it looks like a normal Ball but it's quite in the center or in the end we want to bring it to the center so for that what we can do is provide a size argument to this custom paint which will tell the size of the custom painter so now I can just pass in size let's say the width is 200 the height is 200 as well but constant save it restart and there we go you see we have our ball right over here now the next thing that we need to figure out is how do we animate this well we are going to use explicit animations for this so let's go ahead and create an animation controller so we need with single ticker provider State mix in then we are going to create final animation controller controller I'm just going to speed this process also we'll make this late not final because we have all we are already familiar with this process right we have created an animation controller too many times at this moment so we have animation controller we are vsync this and there we go we have an animation controller with us now now how do I make sure that this ball continuously goes up and down so for this I'm just going to demonstrate how we can do this so the reason we were able to draw a circle at this point was because I declared the center of the circle over here what if I declare this center of the circle over here the ball will be drawn somewhere over here what if I declare the center of the circle over here the ball will be drawn over here what if I declare the center of the circle over here the ball will be over here are you seeing a pattern whenever I'm able to change the center of the circle I'm able to make the ball move up and down so that's what I want to do and that's the animation I want so does that mean I change the offset continuously not really because if we change the offset it is also likely that our width or the X direction is changing in our case only one direction is changing which is the y direction so we need to figure out a way such that only this Y part keeps on animating so for that we can just use a double value right so instead of using an offset we can just use animation double which will keep track of the height because only the Y part is going to change we would have used offset if the Y and the X Direction both were changing in our case only one component is changing which is the y direction so we have animation here then I can set animation equal to tween the beginning value will be 0 and the ending value will be 1. and then I'll just animate and pass in the controller as simple as it gets now I can take this animation and attach it to the custom painter but how will I attach it custom painter doesn't have any property like this what I essentially want to do is pass animation.value so the value of the current animation to this custom painter so that I can make some changes over here in the center part especially so I can just go ahead and wrap my custom Painter with animated Builder I'll pass the animation over here and because of that this custom painter will get rebuilt or will get re- instantiated every single time the animation tween is changing so we have Builder context child and we return a custom painter simple now I want to pass the value to this painter right so I'll accept it from The Constructor because it is a class right if I have a class I can just pass it through the Constructor it's a final double animation value let's call it that and I'm going to accept it from The Constructor this dot animation value cool and now I can just pass in animation.value like this simple so I have animation value pass through the parameter over here and the animation value gets the current value of the animation so just to make sure we are on the same page I'll just print this animation value here I'll restart and you'll see 0.0 is over here and the reason it is only 0.0 and it is not animating is because I have not called controller dot forward so I just need to do controller dot forward and restart and then we have an error the error is there because we haven't passed in a duration so let's go ahead pass the duration in let's put the duration as one second that should be good so the one second is there and now if I restart the app you see these values keep coming in so we have a new value of Animation every single time but the ball here doesn't move and that's because nothing is really associated with this animation value we've got the animation value but we need to make a difference now we need to use this animation value somewhere so how are we going to use it well my proposed algorithm is that we just have to change the height so instead of doing anything over here we are going to change the Y part that was present over here over here this thing over here we need to change this so the next thing we need to understand is this is the value where our ball is when the y direction is zero what if I put size dot height over here all right where will the ball go up or down you see the ball comes over here so that means at zero it is over here at size dot height it is over here so I need to keep animating till 0 changes to size dot height so that means I can just do size dot height minus size dot height into animation value what this means is if the size dot height is let's say 20 then it will become 20 minus the size dot height is again 20 so 20 into 0 at first so in the beginning it will start from somewhere over here and as the animation value increases size dot height minus this entire thing will tend towards zero so if it becomes 0 it will go at the top right so that means we have an animation that goes from here till here let's see if it works if I restart you see this goes from here to here so that means one part of our animation is done going from down to up now how do I make sure that it goes up to down again and for that we'll again have to think to understand this you need to understand that when the ball goes from bottom to up the animation is completed so if the animation is completed what we want to do is just reverse it right so if it goes from bottom to up the animation completes and then we say that hey just go reverse just go back over here and then when it goes back you say just start again and then the loop continues how can we do that to do that we can use listeners right we'll listen to our animation and then just check hey is the animation completed if the animation is completed just reverse so we can just have in our NH state animation dot add status listener add listener is called whenever something an animation changes our status listener is called whenever the status changes so if the animation is completed this listener will get triggered and that's what we want so here I'm just going to say if status is equal to animation status which is the type over here for the status as well and this animation status is an enum so if animation status dot completed so if the animation is completed then I just want to reverse it so I'll just have controller dot reverse and then when I save it I'll restart my app and we see it goes from bottom to up and then again bottom but then it stops it doesn't move ahead it doesn't move ahead because we've just said that hey if the animation is completed reverse it but after that what what should happen after it so here we are going to put an else statement saying that hey if the status is now animation status dot dismissed so if this animation is dismissed meaning the animation stops at the beginning again then you just move ahead again so what's happening over here is if the state is complete that means we are over here it will just reverse it and put it back to its normal position and here in the else if we are saying that hey if it's back in its normal position just move it ahead and if it moves ahead we'll get animation status of completed so it will again reverse and if it reverses it will again come back to its normal position and because of that we'll have animation status dot dismissed which means controller dot forward will run again and make sure you have controller dot forward even over here because if you don't have it over here the animation will not get triggered for the first time for example if I just comment this and restart it is stuck over here it doesn't move ahead because For the First Time animation status listener is not called it is only called when a status changes the animation hasn't started yet that's why the status isn't updated over here so I'll just call controller dot forward here and now if I restart you see the ball will go up and down up and down and that's our animation using custom painter yes you could have done this entire thing with animated Builder and container but that wasn't the point the point was to use custom painter along with animations and knowing that custom painter can be repainted again and again so I hope you understood this example I'm just going to take a quick recap so that you understood what I did we have created a controller we have in its state where we are initializing a controller and the duration of this is one second then we're creating an animation of double type we could have created animation of the type offset but we did not because in our custom painter only one part of the offset had to change and that was the Y component the X component stays as it is where it is that's why we have not used animation offset then we have given it a tween value and animated it then we have our animated Builder over here where we have returned a custom painter if we remove this animated Builder this custom painter won't update even though it has animation.value over here because it doesn't update all the time it will only update when animated Builder tells it to update you see so this is the importance of animated Builder as well now that we have animated Builder we have custom painter over here we've passed the animation.value to this bouncing ball painter and the animation is over here in animation value variable in this class now we are trying to draw a circle so our Circle starts at size dot width divided by 200 so it starts somewhere over here and then the height is dynamic because the height continuously has to change right and to determine this height change what we did was determine where size dot height is where 0 is and based on that we are changing the values because when animation value reaches 1 size dot height will become size dot height because size dot height into one is size dot height and size dot height minus size dot height is 0 so we'll come back over here and when animation value is 0 which is the lowest value animation value can take because tween starts from zero we have size dot height minus 0 which is size dot height so it can animate between these two values and we're just changing that based on this and then we have determined the radius of the circle the color of the circle and we have set should repain to true if we set it to false the animation won't occur it will be stuck in one place so make sure this is true because it continuously has to repin because the height has continuously changing and here to make sure the looping logic is correct we have added a status listener and here we are just checking that hey if the animation completes reverse it and if the animation comes back to its normal position just go ahead so because of that it starts from here go still here and then this part gets executed because of which it goes back to its normal position and then when it goes back that's normal position else if says hey go forward so I hope you understood this example it was a bit tricky to understand if you haven't let me know in the comment section and I'll help you out so this ends our animation video we've learned a lot about implicit explicit page route and custom painter I hope you understood everything thanks for watching and I'll see you in the next video
Info
Channel: Rivaan Ranawat
Views: 18,531
Rating: undefined out of 5
Keywords:
Id: pv4NhV86ZKg
Channel Id: undefined
Length: 168min 6sec (10086 seconds)
Published: Mon Sep 18 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.