All language subtitles for 12. Composition vs. Inheritance - Building Flutter Widgets From Scratch

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
chr Cherokee
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
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fr French Download
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranî)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
fa Persian
pl Polish
pt-BR Portuguese (Brazil)
pt-PT Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu
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.