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,070
Now so far we've seen that we can customize our widgets by doing a number of things. We can either set
1
2
00:00:08,160 --> 00:00:10,580
the properties of each of our widgets,
2
3
00:00:10,590 --> 00:00:17,360
so if our car widget had a color of black, we could simply set its color property to blue.
3
4
00:00:17,470 --> 00:00:22,860
And because our widgets are immutable the old one gets destroyed and a new one gets created with the
4
5
00:00:22,860 --> 00:00:24,600
updated properties.
5
6
00:00:24,630 --> 00:00:31,320
Now we can also change its style or any of the other properties that is predefined by Flutter.
6
7
00:00:31,320 --> 00:00:35,070
So for the slider widget, we can change its activeColor,
7
8
00:00:35,070 --> 00:00:41,220
we can change its divisions etc. But there's only a limited number of these properties that we can change
8
9
00:00:41,550 --> 00:00:48,540
because these rely on preplanning from the Flutter team to create properties for us to change that are
9
10
00:00:48,540 --> 00:00:50,310
commonly needed.
10
11
00:00:50,310 --> 00:00:54,880
So if we wanted to dig deeper when we wanted even more control,
11
12
00:00:54,930 --> 00:01:02,190
then we went into the SliderThemeData where we were able to set the theme for more specific things
12
13
00:01:02,190 --> 00:01:07,260
such as the disabledActiveTickMarkColor or whatever it may be.
13
14
00:01:07,410 --> 00:01:10,420
But then we also get to a dead end right?
14
15
00:01:10,470 --> 00:01:19,450
What if we wanted more customization and we wanted to create a custom widget from scratch? Well in a
15
16
00:01:19,450 --> 00:01:25,190
lot of programming languages if you come from Swift or Java or you've done some development for iOS
16
17
00:01:25,240 --> 00:01:30,640
or Android, then generally the way that we go about this is through inheritance.
17
18
00:01:30,640 --> 00:01:38,260
So we would inherit a component such as the slider, and then we would override some of the properties
18
19
00:01:38,290 --> 00:01:40,400
or methods of those components.
19
20
00:01:40,480 --> 00:01:47,950
And this is generally how we do things in both Android and iOS. But in Flutter, the way that it's built
20
21
00:01:48,040 --> 00:01:51,070
favors composition over inheritance.
21
22
00:01:51,070 --> 00:01:52,320
So what does that mean?
22
23
00:01:52,330 --> 00:01:59,230
It means that we want to try and build things from scratch from the simplest widgets possible and that
23
24
00:01:59,230 --> 00:02:06,810
way Flutter can keep our component's performance and keep our apps fast. So how do we actually go about
24
25
00:02:06,810 --> 00:02:08,680
composing widgets?
25
26
00:02:08,730 --> 00:02:15,600
Well even if we think about a basic widget such as a container, it's actually composed of smaller widgets
26
27
00:02:15,720 --> 00:02:22,260
such as a LimitedBox with a ConstrainedBox with some Align with some Padding with a DecoratedBox. So
27
28
00:02:22,260 --> 00:02:29,900
a whole bunch of widgets that are very basic and do very simple things came together to build a container.
28
29
00:02:30,090 --> 00:02:36,870
And this goes back to that idea of having very simple immutable building blocks that are like small
29
30
00:02:36,870 --> 00:02:38,180
pieces of Lego.
30
31
00:02:38,310 --> 00:02:45,990
And by combining these simple widgets together, we can build a more complex and more interesting widget.
31
32
00:02:47,540 --> 00:02:54,170
So rather than taking a pre-built large widget such as a FloatingActionButton and trying to somehow
32
33
00:02:54,370 --> 00:03:01,460
inherit it and then override certain things about it, it's actually much easier in Flutter to just break
33
34
00:03:01,460 --> 00:03:07,490
it into smaller pieces to see how it's created by looking at the open source code and then just building
34
35
00:03:07,490 --> 00:03:13,880
it together yourself using the simplest, the most basic building blocks that Flutter gives you access
35
36
00:03:13,880 --> 00:03:19,220
to. And that's exactly what we're going to do in this lesson. All right.
36
37
00:03:19,250 --> 00:03:23,000
So we've already done the icon cards, the slide card.
37
38
00:03:23,010 --> 00:03:26,410
Now all we have is this final row to create.
38
39
00:03:26,430 --> 00:03:30,430
So let's go ahead and do that right here.
39
40
00:03:30,680 --> 00:03:35,720
So we currently have two reusable cards and we're going to have to give them some children.
40
41
00:03:35,750 --> 00:03:39,530
So let's add a carChild to the first one.
41
42
00:03:39,800 --> 00:03:45,290
And in this case because we have to stack a number of things on top of each other from the top to the
42
43
00:03:45,290 --> 00:03:53,270
bottom, it also makes sense to add in a column. And in our column, we're going to already set our main
43
44
00:03:53,270 --> 00:03:55,330
AxisAlignment to center.
44
45
00:03:55,370 --> 00:04:03,430
So this way everything gets bundled into the center of the column along the main axis which is the vertical.
45
46
00:04:03,680 --> 00:04:06,950
And then we're going to give our column some children.
46
47
00:04:06,950 --> 00:04:12,000
So the first one is going to be a text widget which simply is going to say 'WEIGHT'.
47
48
00:04:12,170 --> 00:04:18,470
And in this case we're going to use the same style that we've been using so far, which is the klabelTextStyle
48
49
00:04:18,470 --> 00:04:19,820
constant.
49
50
00:04:19,820 --> 00:04:26,960
And now we should be able to see our text show up on screen right in the middle of our column.
50
51
00:04:27,410 --> 00:04:33,770
So the next thing is to add the actual numbers for the weight that the user is going to input.
51
52
00:04:33,770 --> 00:04:38,010
So again we're going to need a variable that's going to keep track of this.
52
53
00:04:38,060 --> 00:04:42,010
So we're going to add it just below height and I'm going to keep it as a whole number as well.
53
54
00:04:42,500 --> 00:04:47,620
And our weight is going to start out being let's say 60 kilos
54
55
00:04:47,690 --> 00:04:48,860
maybe, that should be all right.
55
56
00:04:49,250 --> 00:04:52,460
So we've got our weight number as a variable up there.
56
57
00:04:52,490 --> 00:04:57,640
So we can now add a another text widget just as we have done for our height.
57
58
00:04:57,650 --> 00:05:00,560
We're going to add it in here as the data.
58
59
00:05:00,560 --> 00:05:02,530
So we'll put in the weight
59
60
00:05:02,960 --> 00:05:07,220
and we're going to change it to a string because that's what the text widget wants.
60
61
00:05:07,220 --> 00:05:08,910
So that's what it's going to get.
61
62
00:05:08,960 --> 00:05:11,950
Now our weight is also going to be styled.
62
63
00:05:12,410 --> 00:05:19,040
But this one is going to be styled using the numberTextStyle which is that super large bold looking thing
63
64
00:05:19,100 --> 00:05:20,630
that looks very similar to this.
64
65
00:05:20,630 --> 00:05:23,510
So now we have our weight and we have our starting weight.
65
66
00:05:23,510 --> 00:05:29,510
So all we need to do now is to add some buttons so that the user can actually toggle the weight and
66
67
00:05:29,510 --> 00:05:30,440
their age.
67
68
00:05:30,530 --> 00:05:37,130
So these buttons, we've seen from previously when we used our FloatingActionButtons, look very similar
68
69
00:05:37,130 --> 00:05:42,090
to this right? A round button with an icon child in the middle.
69
70
00:05:42,170 --> 00:05:46,220
So if I go ahead and add in a FloatingActionButton here,
70
71
00:05:46,220 --> 00:05:52,250
so I'm just going to use FAB for short so that trusty Android Studio pulls up the thing I need.
71
72
00:05:52,280 --> 00:05:59,420
And now if I go ahead and hit ENTER and save, then you can see that my FloatingActionButton pops up
72
73
00:05:59,450 --> 00:06:00,790
and it looks really similar.
73
74
00:06:01,190 --> 00:06:08,930
All I would need to do is probably give it a child. And the child is probably going to be an icon and
74
75
00:06:08,990 --> 00:06:10,620
the data for the icon
75
76
00:06:10,640 --> 00:06:15,630
we could probably just use one of the icons and let's just use add.
76
77
00:06:15,650 --> 00:06:21,650
So now you can see we have a round button with an icon in the middle, and it styled in this color because
77
78
00:06:21,650 --> 00:06:27,350
we're kind of using the dark theme but it's pretty easy to change up the color as well by changing the
78
79
00:06:27,350 --> 00:06:36,590
backgroundColor. So we can change it to a nice sort of light gray maybe color and or do 0xFF so fully
79
80
00:06:36,590 --> 00:06:41,570
opaque, 4C4F5E.
80
81
00:06:42,470 --> 00:06:44,180
So this is what we've got so far.
81
82
00:06:44,210 --> 00:06:48,050
So let's change that icon into a white color.
82
83
00:06:48,050 --> 00:06:54,860
So we're going to go into the icon widget and change its color to colors.white for convenience sake
83
84
00:06:55,070 --> 00:06:58,550
and now this is what we have. Now we want two of those
84
85
00:06:58,550 --> 00:07:00,380
so we'll need a row.
85
86
00:07:00,380 --> 00:07:07,590
So I'm going to wrap my FloatingActionButton inside a row widget and we're going to add one more.
86
87
00:07:07,820 --> 00:07:14,270
And I'm going to paste it right below here and maybe we'll add a sizedBox as well so to give it a little
87
88
00:07:14,270 --> 00:07:19,700
bit of space in between. We'll give it a width of maybe 10.
88
89
00:07:19,880 --> 00:07:23,450
Let's try that and see what that looks like.
89
90
00:07:23,450 --> 00:07:23,680
All right.
90
91
00:07:23,690 --> 00:07:25,370
That looks pretty neat.
91
92
00:07:25,460 --> 00:07:31,840
All we would need to do is change my row to be centered along the main axis
92
93
00:07:31,940 --> 00:07:34,970
and now we should have it right in the middle.
93
94
00:07:34,970 --> 00:07:35,210
All right.
94
95
00:07:35,230 --> 00:07:36,110
So it looks good.
95
96
00:07:36,290 --> 00:07:43,970
But the problem is that if we actually read the FloatingActionButton documentations, you can see that
96
97
00:07:43,970 --> 00:07:51,280
it says pretty clearly that use at most a single floating action button per screen.
97
98
00:07:51,470 --> 00:07:55,230
And they have a specific use case.
98
99
00:07:55,310 --> 00:08:01,610
Now it's not just that the documentation recommends against it, but also what if we wanted something
99
100
00:08:01,670 --> 00:08:02,960
that looked different?
100
101
00:08:02,960 --> 00:08:09,260
What if we wanted a custom shape for our floating action button or we wanted it to look exactly the
101
102
00:08:09,260 --> 00:08:11,320
way that we want it to?
102
103
00:08:11,330 --> 00:08:17,600
So so far we've been using pretty much Flutter components out of the box, and we've either tried to combine
103
104
00:08:17,600 --> 00:08:24,440
them together in different ways so that we create our own widgets out of a combination of Flutter widgets,
104
105
00:08:24,890 --> 00:08:32,000
or we've been digging deep into the themes of the widgets that we've been using from material and updating
105
106
00:08:32,150 --> 00:08:37,240
specific parts of it to make it more like the design that we have in mind.
106
107
00:08:37,280 --> 00:08:43,340
But in this lesson I want to show you how you can actually dig into the code for each of these widgets
107
108
00:08:43,370 --> 00:08:48,530
because remember Flutter is completely open source, so all of the components you're looking at the floating
108
109
00:08:48,530 --> 00:08:54,140
action button or the sliders, you can see all of the source code and you can't do that with something
109
110
00:08:54,140 --> 00:08:59,480
like say iOS. You can't actually see how an iOS button is created.
110
111
00:08:59,480 --> 00:09:05,540
The benefit of being able to look at the source code is that if we hold down CONTROL or COMMAND and
111
112
00:09:05,540 --> 00:09:12,020
click on our floating action button, we get taken to our floating_action_button.dart file.
112
113
00:09:12,200 --> 00:09:18,490
And in this file is all the code that's required to create a floating action button.
113
114
00:09:18,530 --> 00:09:24,720
So if we search for its main build method, we can see how this thing is built.
114
115
00:09:24,740 --> 00:09:30,710
So here we go. Here's our build method for our floating action button and it copies over the theme data
115
116
00:09:30,740 --> 00:09:38,510
from the main app theme and it sets the foreground color or an accent theme and then we go about creating
116
117
00:09:38,510 --> 00:09:45,020
the actual button. And you can see that the floating action button is created from a basic component
117
118
00:09:45,020 --> 00:09:51,830
from Flutter called a RawMaterialButton. And this has a number of properties such as what should it do
118
119
00:09:51,830 --> 00:09:56,430
when it's pressed or its elevation etc. and we can dig even deeper.
119
120
00:09:56,450 --> 00:10:02,900
So if we hold down CONTROL or COMMAND, we go to the raw material button and we check out its own build method
120
121
00:10:02,900 --> 00:10:05,060
to see how this thing is built.
121
122
00:10:05,060 --> 00:10:13,870
Then you can see that it's built using a constrainEDbox which has an InkWell which can detect taps.
122
123
00:10:13,880 --> 00:10:20,000
Now this is here because the raw material button is a button right? So it needs to detect touches.
123
124
00:10:20,000 --> 00:10:26,690
But if we didn't need that at all then we could simply just create a material. And if we CONTROL + click
124
125
00:10:26,690 --> 00:10:34,700
further on material then we go to the main material.dart page and if we have a look at its build
125
126
00:10:34,700 --> 00:10:40,130
method, then you can see that this is also built from a number of smaller components.
126
127
00:10:43,040 --> 00:10:49,310
Depending on how deep we want to go down the rabbit hole, we can actually create as custom a design or
127
128
00:10:49,310 --> 00:10:55,130
a component as we need and we don't have to rely on the default Flutter component at all.
128
129
00:10:55,130 --> 00:11:01,400
And you can see that when you go into the packages for Flutter, you can see that there's a lot of packages
129
130
00:11:01,400 --> 00:11:06,910
that people have created when they've built their own custom things such as a custom slider.
130
131
00:11:06,950 --> 00:11:12,320
So for example if we have a look at this slider, you can see this person has built a two thumb range
131
132
00:11:12,320 --> 00:11:19,220
slider which is kind of neat. And you can see that they even tell you how they built this widget.
132
133
00:11:19,220 --> 00:11:26,780
They've basically created it as a pure drawing from scratch in order to display this custom widget.
133
134
00:11:26,780 --> 00:11:33,590
So what I'm trying to say is that the widgets that Flutter provide are super convenient and in most
134
135
00:11:33,590 --> 00:11:35,840
cases they're all that you're going to need.
135
136
00:11:35,840 --> 00:11:41,900
But sometimes if you have a design that you want to implement in particular, then you don't have to be
136
137
00:11:41,900 --> 00:11:48,200
limited to the shapes or the colors or the styles of the default widgets and you can simply just build
137
138
00:11:48,260 --> 00:11:49,140
your own.
138
139
00:11:49,160 --> 00:11:56,780
So let's go about building our own raw material button. And we can create it inside our rows to act as
139
140
00:11:56,810 --> 00:12:03,800
our buttons instead of having to rely on floating action buttons. So right at the bottom I'm gonna create
140
141
00:12:03,830 --> 00:12:12,490
a new stateless widget using my shortcut stless. And I'm going to call my widget a RoundIconButton.
141
142
00:12:12,530 --> 00:12:16,790
So I'm gonna try and be as descriptive as I possibly can.
142
143
00:12:16,790 --> 00:12:23,630
Now my round icon button is going to be built very similar to how the floating action button is built.
143
144
00:12:23,630 --> 00:12:26,930
It's also going to depend on a raw material button.
144
145
00:12:26,930 --> 00:12:31,440
So let's return a RawMaterialButton.
145
146
00:12:31,760 --> 00:12:38,990
And in this case we have a number of properties that we can tap into including things such as the fill
146
147
00:12:38,990 --> 00:12:44,720
Color or the highlightColor or the splashColor or the elevation, but you can see that they all come
147
148
00:12:44,810 --> 00:12:45,690
with default
148
149
00:12:45,710 --> 00:12:51,590
so we only need to set the ones that we actually want to change. So let's go ahead and set some properties
149
150
00:12:51,590 --> 00:12:54,120
for our raw material button.
150
151
00:12:54,200 --> 00:13:01,520
Well firstly it's probably going to need a shape. And you can see that the shape property expects something
151
152
00:13:01,520 --> 00:13:08,870
that is a ShapeBorder and by default it's given a RoundedRectangleBorder.
152
153
00:13:09,020 --> 00:13:10,880
Now that might not be what we want,
153
154
00:13:10,910 --> 00:13:13,300
so let's see what other shapes there are.
154
155
00:13:14,770 --> 00:13:19,960
So when we look at the documentation it tells us that this is the base class for shape outlines and
155
156
00:13:19,960 --> 00:13:24,940
it handles how to add multiple borders together and we can define various shapes.
156
157
00:13:24,940 --> 00:13:31,090
For example we could use circleCorder if we wanted a circle or RoundRectangleBorder for a round rectangle
157
158
00:13:31,330 --> 00:13:34,540
and there's all of these different styles of borders
158
159
00:13:34,570 --> 00:13:35,840
we can choose from.
159
160
00:13:36,040 --> 00:13:43,510
So in our case I'm simply going to choose just a circle border to keep it as a circle and then I'm going
160
161
00:13:43,510 --> 00:13:50,170
to add a fill color to my raw material button and I'm simply just going to copy over the color that
161
162
00:13:50,170 --> 00:13:51,460
I have from before.
162
163
00:13:56,630 --> 00:14:02,570
And now we can simply go over to where we've been using our floating action buttons and we can instead
163
164
00:14:02,630 --> 00:14:07,040
use our custom round icon button instead.
164
165
00:14:07,250 --> 00:14:08,670
So let's check out what it looks like.
165
166
00:14:08,820 --> 00:14:14,540
So it's a little bit smaller than the floating action button and it doesn't seem to have any sort of
166
167
00:14:14,600 --> 00:14:15,280
elevation.
167
168
00:14:15,290 --> 00:14:16,930
It doesn't have any shadows around it.
168
169
00:14:16,940 --> 00:14:19,250
It's just completely flat at the moment.
169
170
00:14:19,250 --> 00:14:23,510
So let's change it and repaint it to the way that we want it to look.
170
171
00:14:23,510 --> 00:14:25,240
Let's maybe update its size.
171
172
00:14:25,280 --> 00:14:27,440
Well how do we know how to do that?
172
173
00:14:27,440 --> 00:14:32,870
Well we can either read through all of the documentation and see which property it is that we need to
173
174
00:14:32,870 --> 00:14:35,440
change. Or even easier,
174
175
00:14:35,450 --> 00:14:40,880
we can take a look at the floating action button and see how the Flutter team actually built this button
175
176
00:14:40,970 --> 00:14:42,080
using the raw material
176
177
00:14:42,080 --> 00:14:46,590
button. We can see that it's got these size constraints.
177
178
00:14:46,690 --> 00:14:54,430
And if we go ahead and try to find this in this file then we can see that it's over here and it's got
178
179
00:14:54,430 --> 00:14:59,380
some constants, minimum size constraints and normal size constraints.
179
180
00:14:59,380 --> 00:15:07,060
So if we look for what these constants are, then we can find that it's actually set to have a box constraint
180
181
00:15:07,420 --> 00:15:12,070
which is tight for a width of 56 and a height of 56.
181
182
00:15:12,100 --> 00:15:17,470
So why do we go ahead and implement this as a constraint in our material
182
183
00:15:17,470 --> 00:15:18,030
button?
183
184
00:15:18,160 --> 00:15:23,530
So it lets add a constraint and put in our box constraints that we've just very conveniently copied
184
185
00:15:23,530 --> 00:15:26,730
over from the Flutter floating action button.
185
186
00:15:26,800 --> 00:15:36,570
Let's hit save and let's see now that our shape is exactly the same as the FAB shape. So let's go ahead
186
187
00:15:36,570 --> 00:15:43,070
and add some elevation to our raw material button and I'm going to add about six pixels of elevation.
187
188
00:15:43,260 --> 00:15:48,490
But right now if we have a look at our button you can see that it's still completely flat.
188
189
00:15:48,510 --> 00:15:53,730
There's actually no shadows and you can zoom in to confirm but there's actually no elevation that's
189
190
00:15:53,730 --> 00:15:58,450
being added unlike this floating action button we've got on the right here.
190
191
00:15:58,570 --> 00:16:00,060
So why is that?
191
192
00:16:00,060 --> 00:16:06,900
Well it's because when all material button doesn't have an onPressed parameter, so it's not able to
192
193
00:16:06,900 --> 00:16:08,240
respond to touches,
193
194
00:16:08,250 --> 00:16:10,660
it's actually in the disabled state.
194
195
00:16:10,710 --> 00:16:14,140
So there's even a setting for the disabled elevation.
195
196
00:16:14,160 --> 00:16:21,180
So if we add that as a six then you can see we now get our elevation. But better than that, we can actually
196
197
00:16:21,180 --> 00:16:28,790
simply just add a onPressed and define what should happen when somebody presses on our round icon button.
197
198
00:16:28,980 --> 00:16:36,480
And if I hit save here, you can see that my shadow stays exactly the same as the floating action button.
198
199
00:16:36,480 --> 00:16:42,540
Now how did I know to change the constraint and also the fact that the onPressed will change whether
199
200
00:16:42,540 --> 00:16:46,830
if the material button is is disabled or enabled?
200
201
00:16:46,830 --> 00:16:49,400
Well of course it's the documentation.
201
202
00:16:49,440 --> 00:16:56,010
So it mentioned here that to define the button size, you change the constraints. And the elevation is
202
203
00:16:56,070 --> 00:17:02,910
for when the button is enabled but not pressed. So buttons are disabled by default, to enable a ,button set
203
204
00:17:02,910 --> 00:17:06,150
it's onPressed property to a non-null value.
204
205
00:17:06,210 --> 00:17:07,880
So there's really no magic here.
205
206
00:17:07,890 --> 00:17:12,370
Everything comes from reading the docs really carefully. Now,
206
207
00:17:12,400 --> 00:17:18,370
the only other things that our material button needs is a child so that we can put in an icon in there.
207
208
00:17:18,820 --> 00:17:21,640
And the icon is going to be different between the left and right.
208
209
00:17:21,640 --> 00:17:24,830
It's gonna be minus on the left and plus on the right.
209
210
00:17:24,850 --> 00:17:31,690
So our raw material button luckily has a child property which we can set and we're going to pass this
210
211
00:17:31,690 --> 00:17:34,030
in into our round icon button.
211
212
00:17:34,300 --> 00:17:39,790
So we're going to set it as a final property and I'm just going to add it as a widget and it's going
212
213
00:17:39,790 --> 00:17:41,170
to be called child.
213
214
00:17:41,290 --> 00:17:49,210
And when we initialize our round icon button, we're going to have a this.child to be have to pass
214
215
00:17:49,210 --> 00:17:56,260
it in to our child property. And then it's going to go right here and be slotted into our raw material
215
216
00:17:56,260 --> 00:17:58,030
button.
216
217
00:17:58,030 --> 00:18:05,020
Now we could leave this as it is and pass in an icon with some icon data but we could also make this
217
218
00:18:05,080 --> 00:18:11,080
a little bit simpler. Given that we're calling this a round icon button, then in most cases it's probably
218
219
00:18:11,080 --> 00:18:14,030
going to be around and it's probably going to contain an icon.
219
220
00:18:14,080 --> 00:18:21,520
So why don't we make our lives easier and just change the child to a icon widget and then only the icon
220
221
00:18:21,520 --> 00:18:24,010
data needs to be passed in?
221
222
00:18:24,100 --> 00:18:31,450
So let's change our property from widget into IconData and we'll just call it icon so that we can pass
222
223
00:18:31,450 --> 00:18:38,380
it in here and we're going to initialize icon instead of an entire child with the icon widget and all
223
224
00:18:38,380 --> 00:18:39,580
of its family.
224
225
00:18:39,580 --> 00:18:48,070
Now we can go into our round icon button and specify an icon which I'm going to change to a FontAwesome
225
226
00:18:48,070 --> 00:18:53,200
icon and I'm going to use their plus sign because it's a little bit bolder and a little bit easier to
226
227
00:18:53,200 --> 00:18:53,950
see.
227
228
00:18:53,950 --> 00:19:01,660
So this is what we have here. And we can now also copy this over and get rid of our floating action button.
228
229
00:19:02,140 --> 00:19:09,310
And I'm going to change this to minus so that I have a minus on the left and a plus on the right.
229
230
00:19:09,640 --> 00:19:13,740
So it's looking pretty neat.
230
231
00:19:13,890 --> 00:19:21,750
So now we've built our very own version of the floating action button and it currently looks pretty
231
232
00:19:21,750 --> 00:19:27,810
much identical to the floating action button. But of course we can customize it to no end because we're
232
233
00:19:27,810 --> 00:19:34,220
using such a basic fundamental building block that we can actually change a lot of its components.
233
234
00:19:34,260 --> 00:19:35,590
For example the shape,
234
235
00:19:35,650 --> 00:19:42,150
so if you didn't want to have just a bog standard circle you could change it to maybe a rounded rectangle
235
236
00:19:42,150 --> 00:19:42,960
for example.
236
237
00:19:42,960 --> 00:19:50,400
So we could choose rounded rectangle border and inside we could change its border radius to use a border
237
238
00:19:50,400 --> 00:19:51,900
radius circular.
238
239
00:19:52,080 --> 00:19:54,400
And then we could provide maybe a radius in there.
239
240
00:19:54,750 --> 00:19:58,920
And now if I hit save we get a rounded rectangle as our buttons.
240
241
00:19:58,920 --> 00:20:05,670
Or you could change it to an ellipse or an oval or even a custom shape. And we could also change the
241
242
00:20:05,670 --> 00:20:06,390
elevation.
242
243
00:20:06,390 --> 00:20:12,460
We could make it completely flat if we don't like the way that the elevated ones look with the shadows.
243
244
00:20:12,570 --> 00:20:16,890
So don't ever feel like you're limited to these default Flutter widgets.
244
245
00:20:16,890 --> 00:20:23,340
The Flutter world really is your oyster and you can build anything you want onto the screen. So I'm going
245
246
00:20:23,340 --> 00:20:31,010
to change this back to my circle because I quite like it as a circle. And I'm also going to change the
246
247
00:20:31,010 --> 00:20:35,830
elevation actually to zero because I actually prefer it completely flat.
247
248
00:20:35,840 --> 00:20:38,890
It looks a lot better to my eye but again it's up to you.
248
249
00:20:38,900 --> 00:20:40,810
You can change it any way you wish.
249
250
00:20:41,000 --> 00:20:45,970
But it's time to actually give our rounded icon button a little bit of functionality.
250
251
00:20:46,040 --> 00:20:51,890
We need to be of to pass in something to the onPressed so that it performs the action of updating the
251
252
00:20:51,890 --> 00:20:52,720
weight.
252
253
00:20:52,730 --> 00:20:54,670
Now we've done this before with the height.
253
254
00:20:54,950 --> 00:21:01,010
So as a challenge I want you to update the weight card here so that when I click on the plus button,
254
255
00:21:01,370 --> 00:21:03,240
it will increase that number.
255
256
00:21:03,260 --> 00:21:06,170
And when I click on the minus button it will decrease the number.
256
257
00:21:06,440 --> 00:21:10,370
So remember set state is your friend. Go ahead and try and complete the challenge.
257
258
00:21:13,280 --> 00:21:13,610
OK.
258
259
00:21:13,650 --> 00:21:21,750
So just as what we've done before with our slider, we need to use set state to update that number here.
259
260
00:21:22,290 --> 00:21:26,900
So we know that the number is currently stored in a variable called weight.
260
261
00:21:27,000 --> 00:21:32,010
And we just have to update it whenever the user clicks on one of these buttons.
261
262
00:21:32,010 --> 00:21:39,740
So inside our round icon button, we need to be able to pass it another property something like onPressed
262
263
00:21:39,750 --> 00:21:40,080
right?
263
264
00:21:40,470 --> 00:21:43,550
But at the moment it obviously doesn't have that property yet.
264
265
00:21:43,560 --> 00:21:53,910
So let's add a final function data type as a onPressed and we're going to add it into our constructor
265
266
00:21:53,970 --> 00:21:54,660
as well.
266
267
00:21:54,660 --> 00:21:57,330
So it'll be this.onPressed.
267
268
00:21:57,360 --> 00:22:00,180
Now it doesn't really matter what you name it. At the moment,
268
269
00:22:00,180 --> 00:22:06,360
I've kept it the same as the name of the raw material button onPressed and I can simply just pass it
269
270
00:22:06,360 --> 00:22:06,770
in here.
270
271
00:22:06,930 --> 00:22:09,100
But the naming is up to you.
271
272
00:22:09,540 --> 00:22:17,310
And I'm going to also mark both the icon and the onPressed as required using my required annotation
272
273
00:22:17,760 --> 00:22:26,190
because our widget's called round icon button so it probably needs to be able to be pressed and it probably
273
274
00:22:26,190 --> 00:22:27,770
needs an icon.
274
275
00:22:27,780 --> 00:22:33,060
So that's my logic for marking these two as required.
275
276
00:22:33,060 --> 00:22:38,730
Now that doesn't really change anything other than the fact that when we create a round icon button,
276
277
00:22:38,820 --> 00:22:43,500
we'll get a warning if we don't have one of those properties added.
277
278
00:22:43,500 --> 00:22:52,530
So for my onPressed on the left which is the first one in the row, I want this to update my weight
278
279
00:22:52,620 --> 00:22:56,150
by decreasing it, because this is the minus symbol.
279
280
00:22:56,280 --> 00:23:03,270
So I'm going to call set state and inside set state I'm going to take my weight property and I'm going
280
281
00:23:03,270 --> 00:23:05,060
to subtract it by 1.
281
282
00:23:05,130 --> 00:23:08,010
And the shorthand for that is --.
282
283
00:23:08,010 --> 00:23:15,690
And in my round icon button that has the plus sign, the onPressed method should increase my weight.
283
284
00:23:15,780 --> 00:23:21,050
So I'm going to call that state and I'm going to increase the weight by adding ++.
284
285
00:23:21,060 --> 00:23:26,310
So it adds it by one every time my round icon button is pressed.
285
286
00:23:26,400 --> 00:23:30,390
So now all we have to do is hit save and check it out.
286
287
00:23:30,390 --> 00:23:34,560
So now if I hit minus, goes down and plus it goes up.
287
288
00:23:34,560 --> 00:23:37,460
So perfect.
288
289
00:23:37,490 --> 00:23:43,420
Now all that's left is to implement the very last card, the age card.
289
290
00:23:43,520 --> 00:23:49,370
So knowing what you know and using what you've learnt, try and complete this as a challenge.
290
291
00:23:49,700 --> 00:23:57,030
And I'll wait for you right here with the solution.
291
292
00:23:57,050 --> 00:23:57,320
All right.
292
293
00:23:57,350 --> 00:24:01,130
So the age card looks pretty much the same as the weight card.
293
294
00:24:01,130 --> 00:24:03,940
So we already know how to create the weight card.
294
295
00:24:04,160 --> 00:24:09,630
And we're going to be reusing this round icon button inside that weight card as well.
295
296
00:24:09,650 --> 00:24:14,920
So right here is our very last card and we're going to give it a card child.
296
297
00:24:15,110 --> 00:24:24,920
And this is going to contain a column. Our column is going to have its main axis centered
297
298
00:24:28,020 --> 00:24:36,720
and it's also going to have some children including a text widget that has the word 'AGE' in it and it's
298
299
00:24:36,720 --> 00:24:41,850
going to have the style that is the constant for the label text style.
299
300
00:24:42,300 --> 00:24:47,130
And then after that text widget, we're going to have another text widget which is going to contain the
300
301
00:24:47,130 --> 00:24:49,500
actual number for the age.
301
302
00:24:49,500 --> 00:24:52,860
So we're going to need to create a variable up at the top.
302
303
00:24:52,920 --> 00:24:59,400
And it's also going to be an integer which is going to start out let's say maybe 20, doesn't really matter,
303
304
00:24:59,730 --> 00:25:00,800
your choice.
304
305
00:25:00,930 --> 00:25:08,310
Now down here we're going to include that age as the text, but of course we have to convert it from an
305
306
00:25:08,310 --> 00:25:15,660
integer to a string. And the style for the age is going to be the KNumberTextStyle which is that large
306
307
00:25:15,750 --> 00:25:16,460
font size.
307
308
00:25:16,770 --> 00:25:21,000
So let's check on our design make sure that everything looks as we expect it to.
308
309
00:25:21,060 --> 00:25:25,870
And now all we need is a row that contains our two buttons.
309
310
00:25:25,950 --> 00:25:32,210
So let's add a row and let's center its content along the main axis,
310
311
00:25:32,220 --> 00:25:36,690
exactly the same way as we did before. And it's going to have two buttons.
311
312
00:25:36,690 --> 00:25:45,660
So we'll add two children and it's going to have our round icon button and the round icon button requires
312
313
00:25:45,720 --> 00:25:46,600
two properties.
313
314
00:25:46,620 --> 00:25:49,400
So those get added in as soon as we hit enter
314
315
00:25:49,470 --> 00:25:50,240
which is kind of neat.
315
316
00:25:50,760 --> 00:26:00,770
And the icon for the left one is going to be FontAwesomeIcons.minus. And once it's pressed what
316
317
00:26:00,770 --> 00:26:07,610
we want to happen is we want to set state and we want to reduce the age by 1.
317
318
00:26:11,390 --> 00:26:18,050
Now let's add a sized box so that we can space out the two buttons from each other.
318
319
00:26:18,050 --> 00:26:25,580
And I'm going to add a width of 10 and then we can simply add another round icon button. And this one
319
320
00:26:25,640 --> 00:26:28,550
the icon is going to be the plus sign,
320
321
00:26:28,580 --> 00:26:38,020
so .plus and when it's pressed, we're going to set state and we're going to add to the age,
321
322
00:26:38,060 --> 00:26:45,560
so age++. Now all we have to do is check to see if we have any errors and we have one here, it's
322
323
00:26:45,590 --> 00:26:47,970
because I forgot a comma.
323
324
00:26:47,960 --> 00:26:55,200
Now if I hit save, Dart is reformatting my code and I can now check out my app.
324
325
00:26:55,310 --> 00:27:03,070
So I've got my weight, my age, my male female height and our entire interface is pretty much complete.
325
326
00:27:03,150 --> 00:27:06,410
So I can click on a card to choose my gender.
326
327
00:27:06,530 --> 00:27:10,070
I can move around the slider to choose my height.
327
328
00:27:10,070 --> 00:27:19,080
So let's put that on my height and then my weight is about, yeah but 63 and my age is a secret.
328
329
00:27:19,460 --> 00:27:28,210
So now we're ready to go ahead and compute our BMI from all the data that is received in this user interface.
329
330
00:27:28,520 --> 00:27:34,010
And in order to do that we need to be able to create a second screen and navigate to it.
330
331
00:27:34,010 --> 00:27:38,990
So this is the first time that we're creating a multi-screen app and we're going to be learning how
331
332
00:27:38,990 --> 00:27:41,740
to do exactly that in the next lesson.
332
333
00:27:41,750 --> 00:27:42,760
So I'll see you there.
38092
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.