All language subtitles for 20. Splitting the App Into Widgets

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: 1 00:00:02,600 --> 00:00:08,810 Let's add a stateful widget. Now which widget should be stateful? 2 00:00:08,810 --> 00:00:10,380 Right now we only have one widget, 3 00:00:10,430 --> 00:00:11,980 the widget in our main file. 4 00:00:12,230 --> 00:00:17,690 We could turn this into a stateful widget but that would have at least two disadvantages which are 5 00:00:17,840 --> 00:00:19,340 kind of connected. 6 00:00:19,340 --> 00:00:22,580 For one, it's already a pretty large widget, 7 00:00:22,640 --> 00:00:27,890 we have a pretty complex widget tree in there and it is a good practice and good idea to split your 8 00:00:27,890 --> 00:00:30,610 large widgets into smaller widgets, 9 00:00:30,770 --> 00:00:34,360 that makes it easier to read them, to work on them, to maintain them 10 00:00:34,490 --> 00:00:40,940 and also from a performance perspective, as soon as you start having stateful widgets that also rebuild 11 00:00:40,970 --> 00:00:47,660 when you change something, you should split your app so that you don't rebuild your entire widget tree 12 00:00:47,900 --> 00:00:49,970 just because a transaction changed. 13 00:00:49,970 --> 00:00:58,640 For example here, the part where we handle the user input, that is where we get the data for the new transaction 14 00:00:58,640 --> 00:01:04,640 but of course this box up here doesn't change just because we added a new transaction, in this box 15 00:01:04,640 --> 00:01:06,250 we don't show the new transaction 16 00:01:06,320 --> 00:01:13,190 so there is no need to repaint this with every new transaction we added or with every change in the 17 00:01:13,190 --> 00:01:15,770 transactions list in general. 18 00:01:15,770 --> 00:01:23,030 So it would make sense to kind of have that list of transactions in a separate widget and therefore 19 00:01:23,030 --> 00:01:31,790 let's create a new file here which I'll name transaction_list.dart. 20 00:01:31,790 --> 00:01:37,790 Now in addition, I now also want to make it really clear which files here are widgets and which files 21 00:01:37,820 --> 00:01:39,120 are normal classes, 22 00:01:39,230 --> 00:01:43,050 for example the transaction.dart file is a normal class, it's not a widget at all. 23 00:01:43,280 --> 00:01:47,620 This here, the transaction class serves as a model for our data and 24 00:01:47,640 --> 00:01:53,140 therefore here, I'll create a new folder, models and move the transaction.dart file in there 25 00:01:53,300 --> 00:01:57,980 and if we had more models, if we had different types of data, different custom types, we would also add 26 00:01:57,980 --> 00:01:58,950 them here. 27 00:01:59,040 --> 00:02:04,790 In the main.dart file, I now also have to adjust my import here and import from 28 00:02:04,880 --> 00:02:08,390 ./models.transaction.dart because I moved that file in there. 29 00:02:08,390 --> 00:02:12,470 Now the transaction list on the other hand is a widget and therefore, I'll also create a new subfolder, 30 00:02:12,800 --> 00:02:13,890 widgets. 31 00:02:13,910 --> 00:02:17,840 Now here I'll move the transaction_list.dart file into the widgets folder. 32 00:02:17,840 --> 00:02:23,210 Now of course right now it might look a bit overkill to have two folders for only two files but the 33 00:02:23,210 --> 00:02:28,160 more widgets we add, the more sense the separation makes because it's then way easier for us to find 34 00:02:28,160 --> 00:02:30,650 out what's a widget and what's a model. 35 00:02:31,550 --> 00:02:38,800 So in the transaction list file here, I want to create a new stateful widget now and for this, I'll use 36 00:02:38,800 --> 00:02:39,730 the shortcut here, 37 00:02:39,730 --> 00:02:45,500 this little snippet the Flutter extension gives me in Visual Studio Code to scaffold out a stateful 38 00:02:45,500 --> 00:02:51,050 widget, it automatically creates the widget class and the state class and it places a couple of markers 39 00:02:51,410 --> 00:02:55,950 where you can now type the name and it inserts the name in all the places that need it. 40 00:02:55,970 --> 00:03:02,720 So here, I'll name this transaction list, using this pascal case naming convention of having uppercase 41 00:03:02,780 --> 00:03:07,620 starting characters for the words but having only one word altogether. 42 00:03:07,790 --> 00:03:13,740 Now in here, I need to import material.dart from the Flutter package because we're using stateful 43 00:03:13,740 --> 00:03:19,130 widget which is exposed by that package, also the state is coming from there 44 00:03:19,160 --> 00:03:25,550 and of course build context, the widget type and the container type here and with all of that, we have 45 00:03:25,550 --> 00:03:28,250 our base widget setup. Now in here, 46 00:03:28,250 --> 00:03:30,730 I want to manage my list of transactions, 47 00:03:30,770 --> 00:03:40,840 so with that I mean my list of transaction objects. In here, we can therefore add a final list of transactions 48 00:03:41,150 --> 00:03:47,880 and for that, make sure you add an import to your transaction model with 49 00:03:47,980 --> 00:03:48,820 ../models/transactions, 50 00:03:48,820 --> 00:03:54,670 dot dot because we need to go up one level where in the widgets folder, dot dot tells Dart to go up 51 00:03:54,730 --> 00:03:55,400 one level, 52 00:03:55,450 --> 00:04:00,490 so out of the widgets folder and then it looks for a new folder, models which then exists in that lib 53 00:04:00,490 --> 00:04:05,500 folder in which we then are and there, in the models folder, it gets access to the transaction.dart 54 00:04:05,500 --> 00:04:06,610 file. 55 00:04:06,610 --> 00:04:13,570 So then we have a list of transactions here and I'll name this user transactions, any name you want and 56 00:04:13,970 --> 00:04:14,540 initially, 57 00:04:14,770 --> 00:04:19,860 I'll have the transactions in here which we previously had in the main.dart file. 58 00:04:19,900 --> 00:04:24,210 So let's grab these two transaction objects here, 59 00:04:24,490 --> 00:04:30,040 cut them in the main.dart file and move them into the transaction list, like this. 60 00:04:30,040 --> 00:04:33,650 So now we have these two dummy transactions here to start with, 61 00:04:33,700 --> 00:04:38,500 by the way if you're wondering why this is final, we will still be able to edit this list as you will 62 00:04:38,500 --> 00:04:38,990 see 63 00:04:39,060 --> 00:04:42,910 and I will come back to why this works and how it works in a second. 64 00:04:42,910 --> 00:04:46,050 So now we have these two transactions in here, now in the build method 65 00:04:46,060 --> 00:04:51,330 here, I of course want to build that list of transaction widgets. In the main.dart file, 66 00:04:51,340 --> 00:04:57,430 I can get rid of that transaction list and also get rid of that input here from the models folder 67 00:04:57,430 --> 00:04:58,400 of course 68 00:04:58,480 --> 00:05:03,820 and if we scroll down to that error which my IDE displays, this is the part where I output the list of 69 00:05:03,820 --> 00:05:06,180 transactions, this is the part which we can grab 70 00:05:06,190 --> 00:05:08,610 now, this entire column here, 71 00:05:08,610 --> 00:05:15,820 cut it out of the main.dart file and of our widget there and add it instead as the return value in our 72 00:05:15,820 --> 00:05:20,140 transaction list here. Now in there, 73 00:05:20,150 --> 00:05:22,880 I'm accessing date format and date format 74 00:05:22,880 --> 00:05:28,250 on the other hand requires us to import the intl package, so we can remove that import from the 75 00:05:28,250 --> 00:05:35,580 main.dart file and add it here in the transaction_list.dart file so that we can format the date and transactions, 76 00:05:35,600 --> 00:05:37,610 that's the wrong property name, here 77 00:05:37,630 --> 00:05:40,230 I renamed it to _userTransactions 78 00:05:40,280 --> 00:05:42,250 should be the name, 79 00:05:42,350 --> 00:05:44,320 so _userTransactions, 80 00:05:44,360 --> 00:05:46,770 so let's use this here. 81 00:05:46,910 --> 00:05:52,400 Now we have the transactions managed in here but now we'll face a new problem, 82 00:05:52,470 --> 00:05:59,880 we're adding transactions from inside our card here with the text fields and that card is actually a 83 00:05:59,880 --> 00:06:06,130 sibling to our transaction list widget which we would add here. 84 00:06:06,180 --> 00:06:09,740 So add transaction list here next to the card, 85 00:06:09,810 --> 00:06:14,840 that's why these ending annotations which the Flutter extension adds are really useful, 86 00:06:14,850 --> 00:06:20,390 so next to the card where you have your text fields and of course to use the transaction list widget 87 00:06:20,430 --> 00:06:26,260 here, you have to import it from ./widgets/transaction_list.dart. 88 00:06:26,490 --> 00:06:32,550 But as I just said, we now have a problem because in transaction lists, we have our list of transactions 89 00:06:32,820 --> 00:06:34,700 and this list should change 90 00:06:34,920 --> 00:06:40,890 but the change is triggered by our text fields which reside in the main.dart file. 91 00:06:40,890 --> 00:06:48,870 So what can we do about that? Well in the end, we have to do something which is called lifting state up, 92 00:06:49,770 --> 00:06:56,370 which means the common denominator of our text field card here and of the transaction list, 93 00:06:56,490 --> 00:07:03,620 so the one widget where we use them both is of course still my homepage widget here. 94 00:07:03,650 --> 00:07:10,670 So there actually is no way around managing our own state, our transactions in here because we need to add 95 00:07:10,670 --> 00:07:16,130 a new transaction to that list from inside our text fields here or with the help of our text fields 96 00:07:16,580 --> 00:07:21,770 and then we need to pass that down to the transaction list which is nice for outputting our transactions 97 00:07:22,040 --> 00:07:28,730 but bad for managing them because if we manage our transactions here in transaction list, then we have 98 00:07:28,730 --> 00:07:35,090 no way of accessing the user transactions list here from outside of that transaction list widget, 99 00:07:35,120 --> 00:07:39,970 the problem just is our text fields here are not inside of the transaction list. 100 00:07:40,040 --> 00:07:45,620 So of course we could alternatively also take that card with all the text fields and add it to our transaction 101 00:07:45,620 --> 00:07:46,090 list, 102 00:07:46,220 --> 00:07:47,570 that would work 103 00:07:47,570 --> 00:07:50,830 but I actually prefer a different approach. 104 00:07:50,900 --> 00:07:56,470 Let's add two new widgets - one for our text input area here, 105 00:07:56,480 --> 00:08:04,330 so for the card with the text fields simply to make that main widget tree a bit leaner and second, let's 106 00:08:04,330 --> 00:08:08,170 then put our text input widget which we'll create 107 00:08:08,320 --> 00:08:10,280 and that transaction list widget, 108 00:08:10,360 --> 00:08:16,510 let's put that together into a new third widget which we then use here in the main widget, in 109 00:08:16,510 --> 00:08:18,910 MyHomePage widget. 110 00:08:18,910 --> 00:08:25,570 The advantage of this will be that the MyHomePage widget can stay stateless and things like the scaffold 111 00:08:25,600 --> 00:08:27,670 and the app bar aren't rebuilt 112 00:08:27,700 --> 00:08:33,250 just because we added a new transaction, because these things really are not affected by a new transaction. 113 00:08:34,000 --> 00:08:36,960 The parts that do need to interact with a new transaction, 114 00:08:37,030 --> 00:08:42,980 so our text input card here and the transaction list will then live in a separate widget. 115 00:08:43,150 --> 00:08:45,550 So let's add two new widgets as I just said, 116 00:08:45,550 --> 00:08:54,130 one is the new_transaction.dart file which will hold our text fields and one is the 117 00:08:54,160 --> 00:09:02,530 user_transactions.dart file. In the new_transaction.dart file, I'll create a stateless 118 00:09:02,530 --> 00:09:11,150 widget which I'll call new transaction and in here, as in all your widget files, you need to import 119 00:09:11,150 --> 00:09:15,300 material.dart so that you unlock stateless widget and so on. 120 00:09:15,360 --> 00:09:19,770 Now let's go back to the main.dart file and grab that card with all the text fields in there, 121 00:09:19,770 --> 00:09:26,910 so this entire card here, grab it, cut it, remove it from the main.dart file and return it here in the 122 00:09:26,910 --> 00:09:29,650 new transaction file. 123 00:09:29,680 --> 00:09:32,430 Now we have the amount and the title controller in here, 124 00:09:32,440 --> 00:09:39,110 so let's add that, let's add these properties in the new transaction widget. The title controller is a 125 00:09:40,320 --> 00:09:46,020 text editing controller, so instantiate that and store it in a final property and the same for the amount 126 00:09:46,020 --> 00:09:46,610 controller, 127 00:09:46,620 --> 00:09:49,590 that's the exact same step we did in the main file earlier. 128 00:09:50,640 --> 00:09:53,750 So now this works, now in the main.dart file, 129 00:09:53,760 --> 00:10:01,830 we can simply use our new transaction widget here, instantiate it and add an import at the top. 130 00:10:01,830 --> 00:10:07,570 Again my IDE automatically added one and whilst this would work, the recommended syntax actually is used 131 00:10:07,650 --> 00:10:12,640 as relative import syntax with ./widgets/new_transaction in this case 132 00:10:12,870 --> 00:10:15,150 and now we have a leaner main.dart file. 133 00:10:15,300 --> 00:10:21,480 Now to avoid having to manage the state in here for these two widgets where actually at the moment, 134 00:10:22,420 --> 00:10:27,320 MyHomePage is the common denominator, to avoid having to manage them here, 135 00:10:27,450 --> 00:10:31,030 we have that new user transactions file here. 136 00:10:31,170 --> 00:10:40,200 That will now hold a stateful widget named user transactions, where as always, you have to import 137 00:10:40,200 --> 00:10:41,300 material.dart 138 00:10:41,470 --> 00:10:47,520 and now here, I actually want to use my new transaction and my transaction list widget. 139 00:10:47,590 --> 00:10:53,940 So the goal here is to return a simple column with these two widgets, actually 140 00:10:53,980 --> 00:10:55,140 basically what we have here, 141 00:10:55,150 --> 00:11:01,150 a column with these two widgets. So you can cut the two widgets here from main.dart file and therefore 142 00:11:01,170 --> 00:11:08,830 also of course get rid of these import statements there and instead in the user transactions file, return 143 00:11:08,960 --> 00:11:14,770 a column because we want to have two widgets sit on top of each other, hence we need a column and in that 144 00:11:14,770 --> 00:11:15,240 column, 145 00:11:15,280 --> 00:11:24,390 add these two widgets and of course also add the imports, so import ./new_transaction.dart and 146 00:11:24,390 --> 00:11:30,630 import ./transaction_list.dart. 147 00:11:30,640 --> 00:11:36,850 Now we can manage our list of transactions here in the user transactions state, 148 00:11:36,850 --> 00:11:38,770 so in the transaction_list.dart file, 149 00:11:38,770 --> 00:11:41,220 we actually don't need a stateful widget, 150 00:11:41,260 --> 00:11:44,380 instead let's use a stateless widget here 151 00:11:44,680 --> 00:11:49,030 and that means we can get rid of this part of the create state 152 00:11:52,730 --> 00:12:03,170 method here and then also of our state class. Cut that list of transactions here, leave the build method 153 00:12:03,170 --> 00:12:11,670 in here of course, we still need that but now go to the user transactions file and there to the user 154 00:12:11,670 --> 00:12:17,110 transaction state and add that _userTransactions property there. 155 00:12:17,190 --> 00:12:20,460 Here I'm also using the transaction type, my transaction model, 156 00:12:20,910 --> 00:12:26,080 so we have to go out of the widgets folder to the models folder and then import my transaction.dart 157 00:12:26,100 --> 00:12:28,350 file here. 158 00:12:28,360 --> 00:12:36,370 Now we're almost there but now we need to pass user transactions to the transaction list widget here 159 00:12:37,150 --> 00:12:38,470 and you learned how that works. 160 00:12:38,470 --> 00:12:39,840 So feel free to do it on your own, 161 00:12:39,850 --> 00:12:42,790 we'll do that and a couple of other things in the next lecture. 17312

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