Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
0
1
00:00:00,660 --> 00:00:08,160
Now you can see that even though all the cards look the same which is how we're able to use our reusable
1
2
00:00:08,160 --> 00:00:16,020
card to style each of them and have them laid out using our expanded widgets, but their content are all
2
3
00:00:16,020 --> 00:00:22,560
different. And usually in Flutter when we're using the widgets that Flutter have created, they tend to
3
4
00:00:22,560 --> 00:00:26,400
address this by having a child property.
4
5
00:00:26,400 --> 00:00:32,480
So for example the expanded widget will have a child or the container will have a child.
5
6
00:00:32,640 --> 00:00:35,810
And this allows us to reuse the same widget
6
7
00:00:35,970 --> 00:00:40,590
but to add custom content for each of these widget that we use.
7
8
00:00:41,040 --> 00:00:47,220
So let's go ahead and create a new child property so that we can do the same with our custom reusable
8
9
00:00:47,220 --> 00:00:50,020
Card. First things first,
9
10
00:00:50,020 --> 00:00:55,600
we're going to create our custom child property and we're gonna call it cardChild.
10
11
00:00:55,630 --> 00:00:59,950
Also this has to be final because our widget is immutable.
11
12
00:01:00,280 --> 00:01:07,170
And then this is going to have the type of widget and it's going to be called cardChild.
12
13
00:01:07,930 --> 00:01:13,180
Well there's a new property but we now have to initialize it because we're getting an error that tells
13
14
00:01:13,180 --> 00:01:17,320
us the final variable car child must be initialized.
14
15
00:01:17,320 --> 00:01:19,600
So we do that in here.
15
16
00:01:19,600 --> 00:01:23,260
Now I don't think the child property should be required.
16
17
00:01:23,350 --> 00:01:31,060
So we don't need to add the required annotation. All we need to do is just write this.cardChild.
17
18
00:01:31,060 --> 00:01:39,190
So that means if we create a new reusableCard, then we can if we wish to add a child to go inside our
18
19
00:01:39,190 --> 00:01:39,790
widget.
19
20
00:01:39,880 --> 00:01:46,790
But if we don't need to have any content, then we can simply just have it as is. Now the final thing is
20
21
00:01:46,810 --> 00:01:54,880
where is this child gonna be placed inside our widget tree? Well it's going to be a child of our container.
21
22
00:01:55,680 --> 00:02:02,410
So we can tap into the container's child property and we're gonna say that whatever cardChild gets passed
22
23
00:02:02,410 --> 00:02:08,320
into this reusableCard will be the child of our container, and that's it.
23
24
00:02:08,320 --> 00:02:09,340
That's all we need to do.
24
25
00:02:10,980 --> 00:02:17,330
Now that we've updated our reusableCard, then it's time to actually add some content.
25
26
00:02:17,520 --> 00:02:23,790
And the first one that we're going to address are these cards that will allow the user to choose their
26
27
00:02:23,790 --> 00:02:24,610
gender.
27
28
00:02:24,630 --> 00:02:29,950
So we've got a icon which comes from a font awesome Flutter package.
28
29
00:02:30,000 --> 00:02:33,960
And then we've got a little bit of text underneath just as a description.
29
30
00:02:33,960 --> 00:02:42,030
So let's get started by customizing our reusableCards at the top row and get the styling down first
30
31
00:02:42,270 --> 00:02:45,010
before we code up any of the functionality.
31
32
00:02:45,060 --> 00:02:49,060
So first things first, we need to get some icons from font awesome.
32
33
00:02:49,140 --> 00:02:50,050
We're going to need the font_
33
34
00:02:50,070 --> 00:02:52,140
awesome_flutter package.
34
35
00:02:52,260 --> 00:02:57,720
So let's go ahead and add this to our pubspec.yaml which at the moment doesn't really contain
35
36
00:02:57,810 --> 00:02:59,410
any custom packages.
36
37
00:02:59,430 --> 00:03:06,270
So right below where we have cupertino icons, we're going to add in font_awesome_flutter. And I'm just
37
38
00:03:06,270 --> 00:03:13,620
going to paste that in here. And then we're going to add the obligatory YAML markup which is going
38
39
00:03:13,620 --> 00:03:20,580
to include a colon here and I'm going to add a caret sign up here as well.
39
40
00:03:20,580 --> 00:03:26,310
And this way we show that we're happy with it using any major versions of font_awesome_flutter that are
40
41
00:03:26,490 --> 00:03:31,240
8.something.something but we're not going to go beyond eight to nine.
41
42
00:03:31,710 --> 00:03:39,390
So now that we've updated our YAML, we're going to click on packages.get and we're going to import
42
43
00:03:39,600 --> 00:03:42,180
the package into our import page.
43
44
00:03:42,450 --> 00:03:51,870
So we're going to import the font awesome package and then we're going to be able to use it inside our
44
45
00:03:51,900 --> 00:04:00,050
reusableCard. So first things first, we're going to target our first card here which is going to look
45
46
00:04:00,050 --> 00:04:01,790
something like this.
46
47
00:04:01,790 --> 00:04:07,940
So we'll have everything centered in the middle of the card and we're going to have our Mars icon from
47
48
00:04:07,940 --> 00:04:10,400
font awesome and a little bit of text below.
48
49
00:04:10,760 --> 00:04:16,850
So this is probably easily achieved using a column as a child.
49
50
00:04:16,850 --> 00:04:25,430
So let's go ahead and add that cardChild which we created earlier on as a property, and the cardChild
50
51
00:04:25,460 --> 00:04:32,990
is going to be a column which is going to have two children. And those two children are going to be firstly
51
52
00:04:33,200 --> 00:04:42,230
a icon which is going to be created from a font awesome icon. And the one that we need is the one called
52
53
00:04:42,290 --> 00:04:48,860
mars, which is generally the male symbol. Now that we have the icon in,
53
54
00:04:48,920 --> 00:04:57,320
I'm going to increase the size of the icon to 80, just make it a lot larger than how it normally is.
54
55
00:04:57,320 --> 00:05:03,470
And then I'm going to add a little bit of a gap between the icon and the text. And to do that we usually
55
56
00:05:03,470 --> 00:05:12,020
use a sizedBox. And we can provide a custom height property to specify how much distance we want between
56
57
00:05:12,080 --> 00:05:14,150
the icon and the text.
57
58
00:05:14,150 --> 00:05:22,210
And in this case I'm going to pick 15. And now finally we can add a text widget and it's just going to
58
59
00:05:22,210 --> 00:05:29,020
say the word male in all caps. And then I'm just going to add a little bit of style which is going to
59
60
00:05:29,020 --> 00:05:38,410
be a text style widget and all I'm going to do is increase the font size to 18 and also change the font
60
61
00:05:38,470 --> 00:05:50,830
color to a custom color and it's going to be 0xFF, so fully opaque, 8D8E98. And you'll see that this
61
62
00:05:50,830 --> 00:05:58,030
is kind of this light gray color, and again all of these colors came from the original Dribbble design
62
63
00:05:58,300 --> 00:06:06,930
just by using the color picker tool. So let's add in all the commas so that when we hit save, Dart willl
63
64
00:06:06,930 --> 00:06:13,930
reformat our code for us. Now at this point if you look at our design, you'll see that we're not actually
64
65
00:06:13,930 --> 00:06:20,170
pulling in the font awesome icon, and this is because after every time you add a new package and you run
65
66
00:06:20,170 --> 00:06:27,130
packages.get, it's actually a good idea to stop the app and run it from scratch so that we do a cold
66
67
00:06:27,130 --> 00:06:34,610
restart and it can incorporate all the things we need, namely the font awesome icons. And now you can see
67
68
00:06:34,610 --> 00:06:39,510
the actual icon that we want onscreen but our column,
68
69
00:06:39,560 --> 00:06:42,430
that is the child of this reusableCard,
69
70
00:06:42,530 --> 00:06:48,510
it's kind of all over the place. But we can add a column property if you remember from before, something
70
71
00:06:48,510 --> 00:06:54,710
called mainAxisAlignment to actually center our column in the parent.
71
72
00:06:54,710 --> 00:06:55,770
So if we hit save
72
73
00:06:55,770 --> 00:07:04,580
now you can see that our icon and our text will go right in the middle of the parent which is the reusable
73
74
00:07:04,640 --> 00:07:06,410
Card.
74
75
00:07:06,590 --> 00:07:13,140
Now we know that in the final design, we're going to have two cards that essentially look pretty much
75
76
00:07:13,140 --> 00:07:13,650
the same.
76
77
00:07:13,650 --> 00:07:19,200
They both have an icon and a bit of text and the styling are exactly the same.
77
78
00:07:19,200 --> 00:07:27,150
So it makes sense then for us to actually reuse this part where we're creating the icon and the gap
78
79
00:07:27,540 --> 00:07:33,600
and the text widget so that we can extract it as a separate widget that we'll be able to reuse anywhere
79
80
00:07:33,600 --> 00:07:34,770
we wish.
80
81
00:07:34,770 --> 00:07:36,890
So here's a challenge.
81
82
00:07:36,930 --> 00:07:44,010
So we're going to create a custom icon content widget. And as a challenge, I want you to try and extract
82
83
00:07:44,490 --> 00:07:51,600
everything that is inside our cardC,hild which is going to be repeated across two cards, into a separate
83
84
00:07:51,660 --> 00:07:52,260
widget.
84
85
00:07:52,650 --> 00:07:59,310
So try and remind yourself how we did it for the reusableCard and pause the video and try to complete
85
86
00:07:59,310 --> 00:08:02,780
this challenge.
86
87
00:08:02,830 --> 00:08:03,130
All right.
87
88
00:08:03,190 --> 00:08:08,870
So in order to do this, we're going to select the highest level of the widget that we want to extract.
88
89
00:08:08,950 --> 00:08:14,650
So we know we have a column with some children but it's the column that we actually want to take out
89
90
00:08:14,800 --> 00:08:20,410
of the main tree and create a separate widget. As long as our cursor is selected on it,
90
91
00:08:20,410 --> 00:08:26,440
then we can head over to our Flutter outline and you can see here in the main widget tree, we've got
91
92
00:08:26,440 --> 00:08:28,820
the corresponding column selected as well.
92
93
00:08:29,080 --> 00:08:34,780
And now all we need to do is right click on it and click on extract widget.
93
94
00:08:34,780 --> 00:08:43,730
And now we get to give it a name and we can call that iconContent and we're going to refactor this
94
95
00:08:43,850 --> 00:08:45,880
into a separate widget.
95
96
00:08:45,890 --> 00:08:51,920
Now as I mentioned before as of the latest version of Dart, we don't need the new keyword, but we now have
96
97
00:08:51,980 --> 00:08:53,500
a icon content widget.
97
98
00:08:53,960 --> 00:08:58,340
And it's now extracted down into here.
98
99
00:08:58,570 --> 00:09:05,500
So now the next challenge for you is we've extracted this widget but we need to be able to reuse it
99
100
00:09:05,770 --> 00:09:07,530
in two places.
100
101
00:09:07,540 --> 00:09:14,860
So one we've already got which is here in the iconContent, but the second place is over here in the
101
102
00:09:14,860 --> 00:09:22,890
second card. Because the icon content describes a column that has a icon and a bit of text.
102
103
00:09:23,020 --> 00:09:28,740
But of course the icon and text are actually different between these two cards.
103
104
00:09:28,780 --> 00:09:34,390
So we need to be able to reuse that icon content widget to be able to display each of these
104
105
00:09:34,480 --> 00:09:39,820
no matter what icon they have. That means you're going to have to change a little bit of code that we
105
106
00:09:39,820 --> 00:09:43,990
currently have in our icon content widget.
106
107
00:09:43,990 --> 00:09:50,620
The end goal is to be able to have that same icon content widget to be able to create both the male
107
108
00:09:50,650 --> 00:09:56,510
icon card and the female icon card by using that custom widget that we created just now.
108
109
00:09:56,530 --> 00:10:03,720
So pause the video and try to complete this challenge. So in order to achieve this we're going to do
109
110
00:10:03,780 --> 00:10:08,370
exactly the same thing that we did in our custom reusableCard,
110
111
00:10:08,490 --> 00:10:13,260
that is create properties to be able to use in the widget that we build.
111
112
00:10:13,260 --> 00:10:20,220
So over here we're going to first remove the default constructor that came when we use that extract
112
113
00:10:20,220 --> 00:10:27,420
functionality that Flutter has where we extracted our icon content, and instead we're going to create our
113
114
00:10:27,420 --> 00:10:35,940
own custom constructors so that we can pass over a value for the icon and also a custom value for the
114
115
00:10:35,940 --> 00:10:36,950
text.
115
116
00:10:36,960 --> 00:10:39,810
So first of all, let's create our properties.
116
117
00:10:39,840 --> 00:10:45,180
So again it's going to have the final keyword and we're going to see that whenever we create properties
117
118
00:10:45,180 --> 00:10:46,480
for our widgets.
118
119
00:10:46,830 --> 00:10:48,960
And then we're going to have a data type,
119
120
00:10:48,960 --> 00:10:52,540
so in this case it's going to be icon data.
120
121
00:10:52,560 --> 00:10:56,820
Now how do I know that it's going to be of icon data data type?
121
122
00:10:56,880 --> 00:11:02,180
Well you can always check the icon widget and you can see that for the property called icon,
122
123
00:11:02,190 --> 00:11:05,130
it's expecting a icon data type.
123
124
00:11:05,490 --> 00:11:07,570
So we've got our icon data
124
125
00:11:07,620 --> 00:11:09,860
and we're simply going to call it icon.
125
126
00:11:10,080 --> 00:11:15,140
And now we can add our second property which is going to be a string.
126
127
00:11:15,180 --> 00:11:21,030
And this is going to be the label that we're going to pass over which is going to go right here so that
127
128
00:11:21,030 --> 00:11:24,390
we'll be able to pass over a female when we're creating the female card, and male
128
129
00:11:24,410 --> 00:11:25,650
when we're creating the male card.
129
130
00:11:25,980 --> 00:11:32,160
So now we're getting some errors because we have yet to initialize these final properties.
130
131
00:11:32,160 --> 00:11:39,840
Remember that final variables can only have one value and that is at the point where they are created.
131
132
00:11:39,840 --> 00:11:46,230
So when this icon content gets created, the part that gets triggered is of course our constructor.
132
133
00:11:46,230 --> 00:11:52,650
So I'm going to create the constructor now. And the constructor is going to have some named properties
133
134
00:11:53,160 --> 00:11:55,130
and it's going to have a
134
135
00:11:55,140 --> 00:11:59,470
this.icon and also a this.label.
135
136
00:11:59,520 --> 00:12:05,930
Now we could make it so that both of these are required but you can also just leave it as it is.
136
137
00:12:05,940 --> 00:12:09,530
So now that we've created our constructor, we've created our properties,
137
138
00:12:09,630 --> 00:12:15,270
It's time to actually specify where these properties are going to go in our main build method.
138
139
00:12:15,270 --> 00:12:18,720
So the first thing that's going to be custom is of course our icon.
139
140
00:12:19,080 --> 00:12:23,310
So it's no longer going to be hard coded as the mars icon.
140
141
00:12:23,310 --> 00:12:27,630
And we're going to change also the text to the label property.
141
142
00:12:27,630 --> 00:12:32,280
So whatever is passed in through this property is going to go right here.
142
143
00:12:32,280 --> 00:12:34,140
That's going to be male and female.
143
144
00:12:34,170 --> 00:12:42,450
And so now when we go into our BMI calculator, the main widget tree, we can update our icon content to include
144
145
00:12:42,540 --> 00:12:45,400
a icon which is going to be a font
145
146
00:12:45,630 --> 00:12:48,350
AwesomeIcon.mars.
146
147
00:12:48,930 --> 00:12:54,300
And then there's also going to be a label which is simply going to be the word 'MALE'.
147
148
00:12:54,420 --> 00:12:56,700
And that's why this expects a string.
148
149
00:12:56,760 --> 00:13:03,400
So let's hit save and now let's go ahead and also do the same for our second card here.
149
150
00:13:03,780 --> 00:13:12,360
So our second reusableCard is also going to have a cardChild, and the child is going to be a widget
150
151
00:13:12,540 --> 00:13:15,510
that's our icon content widget.
151
152
00:13:15,510 --> 00:13:17,510
And it's also going to have an icon
152
153
00:13:17,580 --> 00:13:26,010
but this time, the icon is going to be the venus symbol, venus for women and the label is going to read
153
154
00:13:26,100 --> 00:13:27,750
female. Cool.
154
155
00:13:27,810 --> 00:13:36,240
So now if we hit save and we head over to our app, then you'll see that we have both cards being created
155
156
00:13:36,600 --> 00:13:41,250
and all of the styling is coming from our IconContent.
156
157
00:13:41,250 --> 00:13:47,370
So the size of the icon, the size of the gap between the icon and the text, all of that we didn't have
157
158
00:13:47,370 --> 00:13:48,480
to create again.
158
159
00:13:48,510 --> 00:13:54,630
Instead we're relying on our custom widget IconContent here. And we're just passing in some different
159
160
00:13:54,630 --> 00:14:00,350
values for the parts which need to change, such as the actual icon and the actual label.
160
161
00:14:00,570 --> 00:14:07,200
So you can see that we're kind of starting to create our own widgets rather than just relying on the
161
162
00:14:07,200 --> 00:14:13,020
out-of-the-box Flutter widget. And we're able to use these properties and our constructor to be able
162
163
00:14:13,020 --> 00:14:18,470
to specify some custom content for each of the widgets that we create.
163
164
00:14:19,050 --> 00:14:26,010
At this point, you can see our custom widgets are starting to take up a lot of space in our main input_
164
165
00:14:26,010 --> 00:14:27,690
page.dart file.
165
166
00:14:27,690 --> 00:14:34,530
Now in this case it's actually probably quite a good idea to separate out our IconContent and our reusable
166
167
00:14:34,530 --> 00:14:37,010
Card in two separate Dart files.
167
168
00:14:37,200 --> 00:14:44,550
And this is because we might want to use this in other files as well, maybe in other pages or screens
168
169
00:14:44,550 --> 00:14:45,450
in our app.
169
170
00:14:45,540 --> 00:14:49,080
So it doesn't make sense to have it all crammed into one file.
170
171
00:14:49,170 --> 00:14:55,860
So let's go ahead into our lib and create a new Dart file. And the first one I'm going to call icon
171
172
00:14:56,250 --> 00:15:03,000
_content and then we're just going to click yes to add it to Git. And I'm going to also create
172
173
00:15:03,090 --> 00:15:11,140
a new Dart file that's going to hold our reusableCard, reusable_card and it will create our
173
174
00:15:11,160 --> 00:15:13,020
Dart file as well.
174
175
00:15:13,020 --> 00:15:21,300
So now let's go ahead and take everything that's related to our IconContent and cut it out of the input_
175
176
00:15:21,300 --> 00:15:24,450
page.dart file and instead paste it in here.
176
177
00:15:24,990 --> 00:15:32,710
And of course whenever we're using our material widgets, we always have to import the material package.
177
178
00:15:33,180 --> 00:15:40,200
And we're also going to transplant our reusableCard over to our reusable_car.dart but not before
178
179
00:15:40,200 --> 00:15:43,290
we import our material.dart package.
179
180
00:15:43,620 --> 00:15:46,450
And now we can paste in our reusableCard.
180
181
00:15:46,680 --> 00:15:53,090
Now if we take a look at our IconContent, you can see that we have a lot of things are pretty much hardcoded
181
182
00:15:53,130 --> 00:15:59,610
right? Like the size of the icon or the size of the gap between the icon and the text or things such
182
183
00:15:59,610 --> 00:16:01,790
as the style of the text.
183
184
00:16:02,160 --> 00:16:08,640
Now it often makes sense to simply just take these parts out and create it as a constant at the top of
184
185
00:16:08,640 --> 00:16:09,060
the file.
185
186
00:16:09,570 --> 00:16:14,940
And this way if we think that we want to change the labelTextStyle, then we have to see it right at the
186
187
00:16:14,940 --> 00:16:19,700
top here and we can update and edit it as we need to.
187
188
00:16:19,710 --> 00:16:26,970
And inside here, we simply refer to labelTextStyle. And that way if we have lots of labels or needing that
188
189
00:16:26,970 --> 00:16:31,610
particular style, then they can all refer to this constant.
189
190
00:16:31,690 --> 00:16:38,230
So the final thing to fix in here is that we have a lot of errors because it no longer knows what reusable
190
191
00:16:38,230 --> 00:16:44,380
Card is or what IconContent is because those widgets were removed from this file.
191
192
00:16:44,380 --> 00:16:50,630
So in order to tell our file about those other widgets, we have to import the files that we just created.
192
193
00:16:50,740 --> 00:16:55,360
So icon_content.dart and also reusable_card.dart
193
194
00:16:55,900 --> 00:17:03,700
So now everything should be re-factored into separate files and it'll be much easier to work on each
194
195
00:17:03,700 --> 00:17:06,750
of these components separately if we need to.
195
196
00:17:06,760 --> 00:17:11,700
So just as the native Flutter widget will have their own file,
196
197
00:17:11,740 --> 00:17:18,760
so for example if we hold down COMMAND or CONTROL on Windows and click on our text, and you can see we've
197
198
00:17:18,760 --> 00:17:24,530
got our text.dart file which contains all the code for a text widget.
198
199
00:17:24,550 --> 00:17:33,750
Similarly we have our own custom widgets in their own files. So we can reuse it across our project.
199
200
00:17:33,790 --> 00:17:34,060
All right.
200
201
00:17:34,090 --> 00:17:40,300
So if you find the import getting a bit too much and taking up too much space, it's not a bad idea to
201
202
00:17:40,300 --> 00:17:41,850
simply just collapse it.
202
203
00:17:41,860 --> 00:17:48,430
We never really need to refer to the imports when we're creating our code. And now our main input page
203
204
00:17:48,730 --> 00:17:55,450
has a widget tree that is mostly full of layout and you can more easily see at a glance what it does
204
205
00:17:55,780 --> 00:18:01,390
rather than having the tree completely exploded inside here and a million lines long,
205
206
00:18:01,390 --> 00:18:05,860
we have something that's quite succinct and it's quite easy to figure out what's going on at a glance.
206
207
00:18:06,840 --> 00:18:08,210
In the next lesson,
207
208
00:18:08,250 --> 00:18:15,210
we're going to try and change the color of our card when we click on it, because at the moment nothing
208
209
00:18:15,210 --> 00:18:16,210
really happens.
209
210
00:18:16,350 --> 00:18:19,850
It doesn't seem like as if I could select either of these.
210
211
00:18:19,920 --> 00:18:23,120
So we're going to solve that problem in the next lesson.
211
212
00:18:23,170 --> 00:18:25,260
So for all of that and more, I'll see you there.
24460
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.