Flutter Hooks Tutorial – Hide FAB Animation – 100% Widget Code Reuse

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

What are the benefits of hooks in Flutter? Since Dart is compiled rather than interpreted there's no performance increase from using functions instead of classes.

πŸ‘οΈŽ︎ 2 πŸ‘€οΈŽ︎ u/recursiveG πŸ“…οΈŽ︎ Jan 22 2020 πŸ—«︎ replies

Best package in flutter.

πŸ‘οΈŽ︎ 4 πŸ‘€οΈŽ︎ u/yacomon πŸ“…οΈŽ︎ Jan 22 2020 πŸ—«︎ replies
Captions
code located inside widgets is hard to reuse and furthermore you often end up covering up the lifecycle methods such as in its state with a lot of code you'd love to keep true to the single responsibility principle but how when flutter doesn't let you enter flutter hooks a way to separate your UI logic into independent and composable hooks that will instantly improve code sharing cleanliness and thus also maintainability Oh [Music] welcome to resew coder where you are getting prepared for real app development so that you will get freelance clients or a job and be confident about the apps you built so subscribe it hit the bell to join us on our quest for becoming in demand flutter developers by the end of this tutorial you will know how to create this kind of a floating action button which whenever you scroll the ListView is going to get hidden and then as you scroll up its going to reappear and of course you can build this with just pure flutter stateful widgets but we are going to build all of this using flutter hooks and of course we have a starter project so that you do not have to implement the basic functionality using the classic stateful would you'd approach yourself so practically by all intents and purposes we already have the app working all we need to do is to migrate it from stateful widgets to flutter hooks and you can get this Torah project from the link in the video description and also that link contains the written tutorial where you can also find all of the code written in this video links to the libraries and overall go through this lesson at your own pace first up let's go over this application as it is implemented now without the use of flutter hooks you should know a little something about animation if you want to continue and I have a separate tutorial about animation which you can check out from the cart in the corner what we currently do is that we have a stateful widget called homepage and inside it we have please view and also a floating action button and we are hiding this floating action button with a faith transition also a scale transition using an animation controller right here and how is this all implemented what are we doing in order to control the showing up in hiding of the floating action button well we use a scroll controller on the ListView and what's happening with these two controllers well we first because we are using a state full widget we need to have them defined as state fields here so we have a scroll controller and also animation controller then we mustn't forget to dispose of them whenever the state is disposed this is pretty important and then of course inside init state we set the controllers to be new instances animation controller needs to take in some sort of a vsync which is a ticker provider and if you know something about animation you know that you can provide a ticker provider by mixing in the state object with for example a single ticket provider state mixing so you can immediately see how the boilerplate is just adding up but let's for now just continue with how its implemented currently so once we have the scroll controller and also animation controller instances all set up we also set the duration of the animation and set the floating action button to be initially visible by sending it to one if we set it to zero it's gonna be initially hidden of course and once we have that we then just listen on the scroll controller and whenever the scroll direction changes we are going to animate the floating action buttons controller so if we take a look when we scroll forward in the forward direction which means scrolling up we will show the floating action button if we scroll in the reverse direction so that is down we're going to hide the floating action button and if the scroll Direction is idle so no scrolling is happening as you can see we don't change the state of the floating action buttons animation so we just leave it as it was previously alright so this is really it but as you can see there is a lot of boilerplate here in this homepage state class and also we have just really tightly coupled these two fields to this particular widget that's because with stateful widget which we are currently using we have to keep the controllers as fields inside the state class that's because we need to initialize them here in in its state and dispose of them in the dispose method so with the current approach there is just no way to move these controllers to some different class even if we did we would still need to override this pose and override in its state and initialize and dispose of them right here in this widget or more precisely in its associated state class and of course we could at least extract this call to add a listener to some sort of a helper function some static method in some class but that's about it we simply cannot get rid of most of the boilerplate which we can currently see and in addition having so much code inside one class hinders readability especially if you need to add more state to it down the line so for example if we also wanted to add some sort of a text editing controller later to this class we would have already three controllers here and images become a mess really quickly so while with flutter really everything is possible you can put any kind of code inside your stateful widgets wouldn't it be just better to have the logic and also the setup code elsewhere and have only practically state or less widgets all throughout the app instead of having state full widgets and this is where flutter hooks comes in although we can add mark all of our widgets to be state less we can get pretty close to that by making them hook widgets so first let's go to puff spec llamΓ³ and we are going to add flutter hooks to dependencies its current version is 0.7 point oh and because I cannot promise that there aren't gonna be any breaking changes if you want to follow along with this tutorial make sure to use the same version but you may be also all well if you use a more up-to-date version in the future so once we have flutter hooks we can go to home page and let's discuss how they actually work well they work very much like the state objects of stateful widgets but there is one important difference you can have only one state object associated with one widget there is no way to have multiple states for one stateful widget as you know but with hooks you can have multiple hooks for one hook widget and all of those hooks can hold some sort of a state for example our score controller and also animation controller there are a bunch of predefined hooks which we can use and one of them is for animation controller so we do not need to write any of our own logic in order to grab an instance of animation controller however there are also instances where you need to define hooks yourself for example with our scroll controller there is just no predefined hooks for getting it so this animation thing which I am demonstrating in this tutorial is really the perfect use case for learning flutter hooks we need to create one custom hook and we can also use one predefined hook the first thing you need to do when you migrate to flutter hooks is to get rid of your state full widget and instead use a hook widget so let's actually just all together delete our homepage here and we are going to make the state into a homepage and it's now gonna extend stay but instead it's going to be the hook widget and it's no longer even going to be mixed in with single take a provider state mixing we don't need to provide the ticker because the predefined hook which can grant us an animation controller provides the ticker to the controller itself let's just for now ignore this scroll controller because we need to define our own hook but before we do that let's just focus on the predefined hook forgetting the animation controller so we first can delete the animation controller because we are going to keep any state in the home page hook widget all of the state will be handled by the hooks so we can remove the dispose call to it again we are just leaving scroll controller intact because we will want to copy this code to our custom hook later on of course we cannot initialize this stuff in init state actually in its state is not even present inside a hook widget which is kind of obvious so we can remove also the super calls so now we don't have any field inside a class for the animation controller so how are we going to get it and how can we animate something with it well we are going to use the hooks so we want to use animation controller and we just need to provide again a duration for the animation so k themed animation duration and then this takes in initial value so again we want to make it visible by default because we want to show the floating action button at first before the user Scrolls so if we take a look and the definition of this function or at the signature actually we can see that it returns animation controller which is just what we need so we can now store it inside a final hide fab and in controller and now we can use it by removing the underscores from the previously mentioned field and now we can use this animation controller just as before but we get it by calling use animation controller and we do not need to do any setup in our state of the state full widget but how does this even work it works in the same way that state full widgets and their states work just instead of keeping one state per stateful widget hook widgets keep a list of hooks and when you call those hooks in a defined order all the time so for example there are also other hooks like use state and use stream and so on so final test hook and if you call something like this the hook widget will grant you the instance of the thing in question which you are requesting by calling the use method and then it's up to these hooks to handle initialization within its state and also disposal with the dispose method you don't need to do any of that because these hooks if we just briefly take a look do that for you here you have disposed and a dispossess animation controller for you here you have for example build and it initializes the animation controller for you and the same goes with the ticker which we don't need to provide to the animation control it creates the ticker for you it disposes the ticker for you everything is done for you you don't need to do anything basically you can think of hooks as if you were creating a bunch of small and very focused state objects which are associated with a state full widget all right so we have this predefined hooks sorted out we can now use it throughout our widget code to provide it to the fate transition and also the scale transition but what about our scroll controller how can we create a custom hook for that well all we need to do is to just move this logic from init state and also from this pose to another place and we will also need to pass in the animation controller to that place for example to a function because we no longer have access to the animation controller by the virtue of these two fields being in the same class they're going to be separated now so we need to be able to pass in the animation controller to the scroll controllers hook so let's create a new file with the simplest form of hook and we are going to create it under Lib new folder hooks and let's create a new file there it's gonna be called scroll controller for animation so again the simplest form of hook is really just a function this function will need to return a scroll controller because that's what we want to get at the end so that we can provide it to the list view here so let's create such a function right now scroll controller will be the return type so let's let's call it use scroll controller for animation and it's gonna be taken in an animation controller animation controller and I'm not sure why to import it Cupertino but just make sure that we import material here and in this function we can just copy whatever code we currently have inside the home page which currently is completely broken so we're gonna have a scroll controller in that function without underscore because we are just inside function we don't need to hide it from anything and we want to set it equal to a new scroll controller instance so let's do which is that alright so we have the first part already translated from the state forwarded to this hook secondly we will need to set the listener for this scroll controller so let's cut it out and we are going to call scroll controller and listener remove all of the underscores import flutter rendering for the scroll direction and now the animation controller needs to be the one which is passed in so again nothing changes we just change a bunch of names and that's about it still pretty simple we now have all of the code which is inside in its state then we can return the scroll controller and that's fine but we cannot dispose like how can we dispose of the scroll controller we cannot dispose of it here because that would automatically unregister all of the listeners so we wouldn't do anything with the scroll controller in the end so we need to find a different way to do this but for now let's pretend that not calling this pose is not a problem and if we pretend that everything is fine without calling this pose we can remove all of the code which Carthage's throws errors at us and now we can use our scroll controller and put it inside a final scroll controller and we are gonna call use scroll controller for animation and we are going to pass in the hide tab and in controller so what this means is that now this animation controller for hiding the floating action button is gonna be controlled by our own custom scroll controller so now we can pass this scroll controller to the ListView to be the controller save that and now we can run the app and scroll yay we can see that it hides and that's a very nice thing to see but again let's not forget about the dispose call which we currently do not do so functions are elegant functions are awesome but hooks created as simple functions as we did here just cannot be aware of the lifecycle of their underlying hook widget so this means that whenever you instantiate some sort of a controller or stream controller or whatever which needs to be disposed you cannot just create a simple function for the hook you can create functions whenever you do not need to dispose anything or in other way be aware of the widget lifecycle and you can read more about that from the official documentation for flutter hooks and a link to that is also in the written tutorial so the bottom line is because we need to be able to know about the widget lifecycle and dispose of this scroll controller inside the dispose callback method we cannot just create a function instead we need to have a fully blown hook class if you are familiar with stateful widgets and their state classes so basically if you know the basics of flutter this following call which we are about to write should come to you very naturally there are going to be just a slight naming changes but the structure will remain the same let's just for now leave this functional hook in here so that we can copy code from it and I have a little hack so I currently do not have a code snippet specifically for creating hook classes but we can use the snippet reserved for making stateful widget so SDF UL let's call it with underscore we want to make it package private you're gonna see why in just a bit let's call it scroll controller for animation hook all right once we have that we're gonna remove the duplicate underscores for the associated hook state so let's just remove that of course I could also rename it but whatever and of course this cannot be a stateful widget instead it's going to be a hook so what should this hook hold well this hook should provide a scroll controller and now this associated state will not be a state as is standard with flutter but instead it will be a hook state fairly simple indeed and there is one more type parameter which we need to specify for hook state which is this R and that is the thing which should be provided which is this scroll controller all right so the first type parameter is for the thing which you should provide to the UI and the second type parameter of hook state is its associated hook clasp the last thing which we are gonna change in this basic scaffolding is the return type of the build method it's not gonna be a widget but instead the scroll controller which should be provided and that's it now we need to be able to pass in an animation controller to our hook and similar to how you pass in things to a state full widget the same applies to hooks you need to pass in objects to the hook and then you can use those passed in objects from the state let me demonstrate so we need to pass in this animation controller so let's just copy and paste that to be a field and let's populate it in a constructor so let's just say generate constructor if you don't have the dart data class extension you are really missing out so install that and you can use the same shortcuts as I'm using but anyway you just need to create a constructor let's also make it constant for good measure because we can actually make this animation controller to be final and if you want to learn everything you need to know about constants in Dart check out the tutorial from the cart in the corner and as I said similar to how we can use the field defined inside the state following it from the state class in the same way you can use field defined inside a hook in the hook state class so we can say hook that animation controller and now we have an access to it so that's nice but what do we want to do in this hook state class well we're going to do the same thing we were doing in the home page when it was still just a state full widget inside init hook which is a variation of in its state we actually don't need to call the super that init hook because it's just empty so we don't need to do that unlike with states in stateful widgets where you do need to call the super method and here again all we wanna do is to instantiate a new scroll controller but because we are again inside a class we cannot afford to have a scroll controller like this where we instantiate it inside this method we again need to have it as a class field so let's do just that with an underscore scroll controller and now we can set equal scroll controller to be a new instance of scroll controller and let's again add underscores everywhere where they are needed because just below this instantiation we can add a listener to the scroll controller so really we are just moving the same logic around before it was inside in its state and now it's inside init hook and if this seems like too much to process you can always go through the written tutorial at your own pace from the link in the video description so in order to access the animation controller we need to get whatever is inside the hood class so hook that animation controller which will grant us this one and we need to do the same in the other case of the switch statement that's awesome once the scroll controller is initialized inside in it hook we didn't want to return it from the build method so let's just say scroll controller and what we actually came here for is the dispose method again we do not need to call superdad dispose because it's just empty in its implementation so we can remove that call and from here all we want to do is to call scroll controller that disposed so as you can see hooks are nothing scary they are really just a variation on stateful widgets but you are going to mostly make them more focused you are not going to probably keep a bunch of fields in just one hook you are instead going to branch out into multiple hooks and that's because the hook widget can use multiple hooks and manages one state alright so why did we make this class package private which means that we currently cannot access it from the home page hook widget well we did that because there is a bit of boilerplate which you need to call whenever you want to use a proper hook class so instead of putting this boilerplate directly inside home page we are still just going to call you scroll controller for animation which will hide this boilerplate in this function so what do we wanna do here we want to call a hook that use and now provide the instance which we want to use so this is going to be the scroll controller for animation hook and also we will need to pass in the animation controller and that's it so because we did not change the public interface and also we did not change the functionality basically except for the fact that now the scroll controller is really disposed we don't need to do any changes to the homepage hook widget because it still just calls this use scroll controller for animation method or function because it's outside the class and because of this we can just run the app again take a look at it and of course it's still going to work very nicely and you may argue that we have just added a lot of boilerplate I mean this is just crazy and you are correct hooks are not a silver bullet and you have to constantly weigh other factors when you decide whether to use or not to use hooks for example using a hook only in one widget as we are doing now is completely ludicrous doesn't make sense and it's not a good time investment however if you have ten of these kinds of widgets or even just three or two widgets which need to hide their floating action button then using a hook like this which we have just created is very much beneficial so you really need to weigh the pros and cons whenever you want to use hooks of course when you can use a predefined hook like with this animation controller just use it always do not even think about that because when something is already there for you you don't need to invest more time into implementing that hook why not why not to use something which will make your life easier I know that this tutorial may be a bit more on the advanced side especially with all of the hook code we have written here so if you want to go through this at your own pace once again and to get all of the code check out the written tutorial available from the link in the description and also if you are serious about becoming a gray Flattr developer who can build real apps for clients or at the job go to flutter dot education a link is also in the description to get the top curated flutter news and resources aimed at improving your app development career over there you can also subscribe to my mailing list to get the best photo resources delivered weekly right into your inbox and if you don't miss more tutorials like this be sure to subscribe to this channel and also join notification squad by hitting the Bell button to make sure you grow your flutter skills because here on reso coder I am determined to provide you with the best tutorials and resources so that you will become an in-demand flutter developer if this video helped you with understanding flutter hooks how to implement them how to use the predefined ones give it a like and also share it with our developers who will surely benefit from this do leave a comment if you have anything to say and see you in the next video [Music]
Info
Channel: Reso Coder
Views: 24,636
Rating: undefined out of 5
Keywords: resocoder, tutorial, programming, code, programming tutorial, flutter, flutter tutorial, flutter hooks, flutter state management, flutter stateful widget, flutter animation, flutter animation tutorial, flutter fab button, flutter fab animation, flutter floating action button, flutter floating action button animation
Id: LjITiYjB1Q0
Channel Id: undefined
Length: 29min 48sec (1788 seconds)
Published: Tue Jan 21 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.