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.