All language subtitles for 4. Stateful Widget Lifecycle Methods

af Afrikaans
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bn Bengali
bs Bosnian
bg Bulgarian
ca Catalan
ceb Cebuano
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
tl Filipino
fi Finnish
fr French Download
fy Frisian
gl Galician
ka Georgian
de German
el Greek
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
km Khmer
ko Korean
ku Kurdish (Kurmanji)
ky Kyrgyz
lo Lao
la Latin
lv Latvian
lt Lithuanian
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mn Mongolian
my Myanmar (Burmese)
ne Nepali
no Norwegian
ps Pashto
fa Persian
pl Polish
pt Portuguese
pa Punjabi
ro Romanian
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
st Sesotho
sn Shona
sd Sindhi
si Sinhala
sk Slovak
sl Slovenian
so Somali
es Spanish
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
te Telugu
th Thai
tr Turkish
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu
or Odia (Oriya)
rw Kinyarwanda
tk Turkmen
tt Tatar
ug Uyghur
Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated: 0 1 00:00:00,330 --> 00:00:08,300 Now in the last lesson we used our scratch.dart file to learn more about futures and async and await. 1 2 00:00:08,490 --> 00:00:13,740 But we don't need this file anymore so you can either delete it or you can keep it around for reference 2 3 00:00:13,740 --> 00:00:14,580 in the future. 3 4 00:00:14,640 --> 00:00:16,490 It won't affect your project. 4 5 00:00:16,590 --> 00:00:23,460 Now let's head back into our loading screen and if we take a look at the code now, it should make a bit 5 6 00:00:23,460 --> 00:00:25,500 more sense to you. 6 7 00:00:25,570 --> 00:00:32,530 You can see that we're creating a new geolocator object that comes from geolocator.dart. And then 7 8 00:00:32,530 --> 00:00:37,110 we're using that object to get the current position. We're calling getCurrentPosition 8 9 00:00:37,810 --> 00:00:45,520 and this is a method that's inside geolocator. And we provide the amount of accuracy we want for this 9 10 00:00:45,520 --> 00:00:46,460 location. 10 11 00:00:46,690 --> 00:00:53,770 And we're going to choose low so that we don't use up all the battery. And because it takes time to get 11 12 00:00:53,770 --> 00:00:55,370 the current position 12 13 00:00:55,390 --> 00:01:01,570 this method is asynchronous and it will happen independently of whatever else you decide to try and 13 14 00:01:01,570 --> 00:01:09,560 do. But because in most cases we can only proceed forwards with for example printing the position we 14 15 00:01:09,560 --> 00:01:14,230 got back or with using that position in getting some weather data, 15 16 00:01:14,360 --> 00:01:22,010 then we're adding the async keyword to modify our function. And that gives us access to the await keyword 16 17 00:01:22,100 --> 00:01:30,700 which basically says wait until this completes before you continue doing anything. If we didn't have 17 18 00:01:30,700 --> 00:01:37,650 this await keyword, then we could still have a position but it won't be an actual position. 18 19 00:01:37,810 --> 00:01:40,650 It will be a future position. 19 20 00:01:40,720 --> 00:01:43,240 It's just like that order number. 20 21 00:01:43,240 --> 00:01:45,290 It will have a value in the future 21 22 00:01:45,310 --> 00:01:52,300 once this process completes. But at the point where this code is called or when it's triggered, this is 22 23 00:01:52,300 --> 00:01:53,460 just a receipt. 23 24 00:01:53,470 --> 00:01:55,760 It's not an actual coffee. 24 25 00:01:55,900 --> 00:02:03,220 And right now if I was to print out this position variable, it won't be an actual position that actually 25 26 00:02:03,220 --> 00:02:09,510 comes out. And we can show that by changing this from running scratch.dart to main.dart. 26 27 00:02:09,610 --> 00:02:20,040 And now if I press run and I go ahead and click on get location, then you can see that what's being printed 27 28 00:02:20,040 --> 00:02:24,320 in my console on the main.dart, so we can close down scratch.dart 28 29 00:02:24,330 --> 00:02:31,920 if you want, is an instance of future position. This is kind of like you promise your friends to go and 29 30 00:02:31,920 --> 00:02:36,540 grab them a coffee and all you did is come back with the receipt. 30 31 00:02:36,660 --> 00:02:38,430 Now they're not going to want the receipt. 31 32 00:02:38,430 --> 00:02:40,590 They're going to want the actual coffee. 32 33 00:02:40,740 --> 00:02:47,880 So that's why we're adding that await keyword in front of the method call to say that, wait for this 33 34 00:02:47,880 --> 00:02:51,380 to finish before you assign this value to the position. 34 35 00:02:51,840 --> 00:02:58,620 So that way we actually get an actual position or an actual coffee, rather than just the promise of a 35 36 00:02:58,620 --> 00:03:01,860 coffee that's going to be there in the future. 36 37 00:03:01,920 --> 00:03:08,880 And now if I click on get location, you can see the actual location gets printed rather than just a future. 37 38 00:03:10,410 --> 00:03:14,950 So it's all very well and good that we can get the location when we press on this button. 38 39 00:03:15,000 --> 00:03:23,640 But what if we wanted the location as soon as our screen loads up? Because in our weather app, as soon 39 40 00:03:23,640 --> 00:03:29,030 as we open up the app, it's going to trying and detect our location and based off that location, it's gonna 40 41 00:03:29,070 --> 00:03:30,120 get the weather. 41 42 00:03:30,120 --> 00:03:35,750 It doesn't make sense to force the user to press a button to say get weather or get location, 42 43 00:03:35,760 --> 00:03:46,980 that seems a bit extra. So how would I call get location if I wanted it to happen as soon as my screen 43 44 00:03:47,070 --> 00:03:51,630 loads up? Well in order to do this 44 45 00:03:51,630 --> 00:03:55,980 we have to learn about widget lifecycles. 45 46 00:03:55,980 --> 00:04:01,410 We know that stateless widgets are basically just like very simple Lego blocks right? 46 47 00:04:01,410 --> 00:04:03,240 You can't saw them in half, 47 48 00:04:03,240 --> 00:04:04,480 you can't change them. 48 49 00:04:04,560 --> 00:04:11,400 You can't do anything with them unless you decide to destroy them and create a new one. 49 50 00:04:11,700 --> 00:04:18,340 And you have to keep destroying and creating new ones every time you want a change in a stateless widget. 50 51 00:04:18,360 --> 00:04:24,300 So for these widgets, their lifecycle methods are very simple. There's only one that you should be concerned 51 52 00:04:24,300 --> 00:04:29,270 about and that's the build method. When the widget gets built 52 53 00:04:29,280 --> 00:04:32,820 this method will be called and inside here, 53 54 00:04:32,820 --> 00:04:39,180 you will create whatever appearance or widget you want to show up on screen. 54 55 00:04:39,270 --> 00:04:46,830 Now on the other hand, we also have our stateful widgets and we know that these stateful widgets can 55 56 00:04:46,830 --> 00:04:52,410 be combined and we can track the state using a state object. 56 57 00:04:52,440 --> 00:05:00,340 Now that state object is there keep track of variables such as what is the configuration of my widgets, 57 58 00:05:00,450 --> 00:05:02,820 what are the properties of my widgets. 58 59 00:05:02,910 --> 00:05:11,270 And I can change all of those variables by using a set state and it will update my app. Now 59 60 00:05:11,280 --> 00:05:19,000 in this case, the state object actually lives a lot longer and so it's got more lifecycle methods. 60 61 00:05:19,020 --> 00:05:25,930 There is an init state, which gets triggered when that state initially gets initialized. 61 62 00:05:26,020 --> 00:05:31,140 There's of course the build method which gets triggered when the widgets are actually built and will 62 63 00:05:31,140 --> 00:05:38,310 show up on screen. And then there's a deactivate method which gets called when that stateful widget 63 64 00:05:38,340 --> 00:05:39,550 gets destroyed. 64 65 00:05:41,150 --> 00:05:48,680 So just as we humans are born and we grow up we go through different life stages and then we also die, 65 66 00:05:48,710 --> 00:05:55,940 so do our stateful widgets. But we can tap into each of those stages in the lifecycle if we wanted different 66 67 00:05:55,940 --> 00:05:59,330 things to happen at various times. 67 68 00:05:59,360 --> 00:06:05,180 Now I just want to show you when these lifecycle methods will get triggered. And to do so, I'm pulling 68 69 00:06:05,180 --> 00:06:09,670 up that previous file that we had, the navigation demo that we used earlier on. 69 70 00:06:09,970 --> 00:06:12,310 Now you don't have to write any of the code, 70 71 00:06:12,350 --> 00:06:14,900 I just want to show you what actually happens. 71 72 00:06:14,990 --> 00:06:21,870 It's enough to just follow along. Here we still got our screen 1 which is a stateless widget. 72 73 00:06:21,940 --> 00:06:29,330 We've got our screen 2 which is currently a stateful widget. And I've made our app start out at a screen 73 74 00:06:29,390 --> 00:06:30,940 1 which is the first route. 74 75 00:06:31,490 --> 00:06:38,590 So when I run my app, I head over to the screen 1 which only has a single button that pushes me onto 75 76 00:06:38,650 --> 00:06:40,300 screen 2. 76 77 00:06:40,400 --> 00:06:47,300 Now once I'm on screen 2, I want to be able to show you when these lifecycle methods actually get called. 77 78 00:06:47,870 --> 00:06:54,950 Inside our state object, I'm going to tap into a number of methods that come from the parent class, the 78 79 00:06:54,950 --> 00:07:00,440 state class. One of those is the initState method. 79 80 00:07:00,440 --> 00:07:06,830 And if we click on this initState, hold down CONTROL + J or CONTROL + Q, you can see that this 80 81 00:07:06,830 --> 00:07:11,240 is called when an object is inserted into the tree. 81 82 00:07:11,340 --> 00:07:18,800 And this means that when we create our stateful widget as soon as it's inserted into the tree, it's 82 83 00:07:18,800 --> 00:07:20,210 going to call initState. 83 84 00:07:20,210 --> 00:07:22,580 So this is the first thing that happens. 84 85 00:07:22,690 --> 00:07:32,000 So inside here I'm going to add a print statement saying 'initState called'. And that will print whenever 85 86 00:07:32,330 --> 00:07:39,020 this method gets triggered. And it will get triggered automatically at a particular stage in the life 86 87 00:07:39,170 --> 00:07:41,150 of this state object. 87 88 00:07:41,150 --> 00:07:44,030 Now the second one that gets triggered, 88 89 00:07:44,030 --> 00:07:49,160 so the second point in the lifecycle, is going to be the build method. 89 90 00:07:49,160 --> 00:07:54,950 Now inside here, I'm also going to add a print statement saying 'build called'. 90 91 00:07:57,880 --> 00:08:03,400 And finally there's also another method that comes from the parent class that I want to show you which 91 92 00:08:03,400 --> 00:08:12,350 is called deactivate. And deactivate will get triggered when this stateful widget gets destroyed. 92 93 00:08:12,370 --> 00:08:15,380 So let's add a print statement in here as well. 93 94 00:08:18,730 --> 00:08:27,490 Now let's go ahead and click run for our changes to go through. And in our console you can see that as 94 95 00:08:27,490 --> 00:08:32,320 soon as I click on this button, I should head over to screen 2. 95 96 00:08:32,830 --> 00:08:38,860 Now as soon as that stateful widget is created and inserted into the widget tree, initState gets 96 97 00:08:38,860 --> 00:08:39,330 called. 97 98 00:08:39,340 --> 00:08:40,830 So that gets printed in here. 98 99 00:08:41,410 --> 00:08:48,370 And then as soon as it builds all of the widgets inside the screen which is just my button and my scaffold 99 100 00:08:48,380 --> 00:08:57,070 etc. then we get billed called. Now every time I make a change in the screen or I change one of the properties 100 101 00:08:57,370 --> 00:09:01,750 that the widgets depend on, then build will get called again and again and again. 101 102 00:09:01,780 --> 00:09:05,420 And this is one of the most frequently used lifecycle methods. 102 103 00:09:05,620 --> 00:09:14,160 But at the very end when I click on go back to screen 1, screen 2 is going to pop off, 103 104 00:09:14,170 --> 00:09:16,330 that means it's going to be destroyed. 104 105 00:09:16,330 --> 00:09:18,140 It will no longer exist. 105 106 00:09:18,280 --> 00:09:22,300 And that is the time when deactivate will get called. 106 107 00:09:22,360 --> 00:09:28,770 So there are other lifecycle methods but these are probably the most useful and the ones that you'll 107 108 00:09:28,780 --> 00:09:32,660 actually come across and need when you're creating Flutter apps. 108 109 00:09:32,740 --> 00:09:39,100 So we know that if we want something to happen the moment that our stateful widget is created and 109 110 00:09:39,130 --> 00:09:45,730 add into the tree, then we're going to put our code inside initState. If we want something to happen 110 111 00:09:45,940 --> 00:09:47,420 every single time 111 112 00:09:47,440 --> 00:09:52,180 our stateful widget gets rebuilt, then we'll put it into the build method. 112 113 00:09:52,180 --> 00:09:58,120 And finally if we want something to happen when our stateful widget gets destroyed, then we would put 113 114 00:09:58,120 --> 00:10:02,760 the code inside the deactivate method. 114 115 00:10:03,000 --> 00:10:08,800 So now using what we've learned on lifecycle methods, here's a challenge for you. 115 116 00:10:08,850 --> 00:10:17,340 I want you to change our code so that the position gets printed into the console without tapping on 116 117 00:10:17,340 --> 00:10:18,250 any buttons. 117 118 00:10:18,270 --> 00:10:24,140 In fact you can go ahead and delete the entire contents of the scaffold. 118 119 00:10:24,210 --> 00:10:27,330 What should happen is as soon as our app runs 119 120 00:10:27,480 --> 00:10:35,430 and as soon as this loading screen appears inside the phone then we should see our position being printed 120 121 00:10:35,430 --> 00:10:36,600 in the console. 121 122 00:10:36,870 --> 00:10:40,260 And this will rely on what you've learned from this lesson. 122 123 00:10:40,290 --> 00:10:45,470 Pause the video and try to complete that challenge all right. 123 124 00:10:45,500 --> 00:10:49,640 So currently when we run our app all we get is just the blank screen. 124 125 00:10:49,650 --> 00:10:54,020 There's nothing inside build, just a blank scaffold. 125 126 00:10:54,020 --> 00:10:58,910 So we're not gonna use any buttons to trigger getting the location. 126 127 00:10:58,910 --> 00:11:06,360 Instead we're going to add a initState to our loading screen. And because we know that this is going 127 128 00:11:06,360 --> 00:11:11,390 to be triggered as soon as our stateful widget gets created, 128 129 00:11:11,390 --> 00:11:15,330 so it's the moment that this appears on screen. 129 130 00:11:15,350 --> 00:11:21,380 Now it's important to know that initState only gets called once and it's only the moment when that 130 131 00:11:21,380 --> 00:11:24,180 state gets initialized and gets created. 131 132 00:11:24,290 --> 00:11:30,800 But something like build even though it does get called when our widget gets built onto the screen, but 132 133 00:11:30,800 --> 00:11:35,070 it gets caught every single time that our widgets rebuild. 133 134 00:11:35,090 --> 00:11:42,290 So every time a piece of text changes or an image changes or this animation, then build will be called again 134 135 00:11:42,290 --> 00:11:48,110 and again and again. And very often you don't want to put code in there that will get called repeatedly 135 136 00:11:48,470 --> 00:11:51,170 because it's very expensive. 136 137 00:11:51,170 --> 00:11:53,740 Instead we're going to put it inside initState. 137 138 00:11:53,780 --> 00:11:57,950 And so inside initState, we're going to call get location. 138 139 00:11:58,130 --> 00:12:05,840 And now if I go ahead and hot restart my app to make it reinitialize this particular stateful widget, 139 140 00:12:06,200 --> 00:12:11,720 then you can see as soon as it goes on the screen, I get my position printed in the console. 140 141 00:12:11,720 --> 00:12:19,940 I didn't have to press anything at all. So our lifecycle method are really useful if we want to tap in 141 142 00:12:19,940 --> 00:12:28,490 to a particular moment in the life of our stateful widgets. If we wanted to save a piece of data just 142 143 00:12:28,490 --> 00:12:34,670 before the stateful widget gets destroyed or if we want to deallocate something from memory or if we 143 144 00:12:34,670 --> 00:12:40,970 want to create a new object as soon as the stateful widget gets initialized, these are the methods that 144 145 00:12:40,970 --> 00:12:49,790 we can tap into to make our code run at a particular time. And in our case we're making our get location 145 146 00:12:49,790 --> 00:12:57,170 method run in the moment as soon as our loading screen state gets initialized which is going to be at 146 147 00:12:57,170 --> 00:13:02,240 the very start and we only make it run once. Now 147 148 00:13:02,240 --> 00:13:08,660 at the moment, we're getting our location and we're importing our geolocator all inside our loading 148 149 00:13:08,660 --> 00:13:11,170 screen which is kind of not its job right? 149 150 00:13:11,660 --> 00:13:17,570 So in the next lesson we're going to learn more about checking to see if the user has given permission 150 151 00:13:17,570 --> 00:13:19,030 to get the location. 151 152 00:13:19,160 --> 00:13:26,010 And we're also going to refactor all of the location related work into our location.dart file. 152 153 00:13:26,060 --> 00:13:29,240 So for all of that and more, I'll see on the next lesson. 17639

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.