Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranรฎ)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Persian
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Russian
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
0 Now you can see that even though all the cards look the same which is how we're able to use our reusable 1
card to style each of them and have them laid out using our expanded widgets, but their content are all 2
different. And usually in Flutter when we're using the widgets that Flutter have created, they tend to 3
address this by having a child property. 4
So for example the expanded widget will have a child or the container will have a child. 5
And this allows us to reuse the same widget 6
but to add custom content for each of these widget that we use. 7
So let's go ahead and create a new child property so that we can do the same with our custom reusable 8
Card. First things first, 9
we're going to create our custom child property and we're gonna call it cardChild. 10
Also this has to be final because our widget is immutable. 11
And then this is going to have the type of widget and it's going to be called cardChild. 12
Well there's a new property but we now have to initialize it because we're getting an error that tells 13
us the final variable car child must be initialized. 14
So we do that in here. 15
Now I don't think the child property should be required. 16
So we don't need to add the required annotation. All we need to do is just write this.cardChild. 17
So that means if we create a new reusableCard, then we can if we wish to add a child to go inside our 18
widget. 19
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
where is this child gonna be placed inside our widget tree? Well it's going to be a child of our container. 21
So we can tap into the container's child property and we're gonna say that whatever cardChild gets passed 22
into this reusableCard will be the child of our container, and that's it. 23
That's all we need to do. 24
Now that we've updated our reusableCard, then it's time to actually add some content. 25
And the first one that we're going to address are these cards that will allow the user to choose their 26
gender. 27
So we've got a icon which comes from a font awesome Flutter package. 28
And then we've got a little bit of text underneath just as a description. 29
So let's get started by customizing our reusableCards at the top row and get the styling down first 30
before we code up any of the functionality. 31
So first things first, we need to get some icons from font awesome. 32
We're going to need the font_ 33
awesome_flutter package. 34
So let's go ahead and add this to our pubspec.yaml which at the moment doesn't really contain 35
any custom packages. 36
So right below where we have cupertino icons, we're going to add in font_awesome_flutter. And I'm just 37
going to paste that in here. And then we're going to add the obligatory YAML markup which is going 38
to include a colon here and I'm going to add a caret sign up here as well. 39
And this way we show that we're happy with it using any major versions of font_awesome_flutter that are 40
8.something.something but we're not going to go beyond eight to nine. 41
So now that we've updated our YAML, we're going to click on packages.get and we're going to import 42
the package into our import page. 43
So we're going to import the font awesome package and then we're going to be able to use it inside our 44
reusableCard. So first things first, we're going to target our first card here which is going to look 45
something like this. 46
So we'll have everything centered in the middle of the card and we're going to have our Mars icon from 47
font awesome and a little bit of text below. 48
So this is probably easily achieved using a column as a child. 49
So let's go ahead and add that cardChild which we created earlier on as a property, and the cardChild 50
is going to be a column which is going to have two children. And those two children are going to be firstly 51
a icon which is going to be created from a font awesome icon. And the one that we need is the one called 52
mars, which is generally the male symbol. Now that we have the icon in, 53
I'm going to increase the size of the icon to 80, just make it a lot larger than how it normally is. 54
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
use a sizedBox. And we can provide a custom height property to specify how much distance we want between 56
the icon and the text. 57
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
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
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
color to a custom color and it's going to be 0xFF, so fully opaque, 8D8E98. And you'll see that this 61
is kind of this light gray color, and again all of these colors came from the original Dribbble design 62
just by using the color picker tool. So let's add in all the commas so that when we hit save, Dart willl 63
reformat our code for us. Now at this point if you look at our design, you'll see that we're not actually 64
pulling in the font awesome icon, and this is because after every time you add a new package and you run 65
packages.get, it's actually a good idea to stop the app and run it from scratch so that we do a cold 66
restart and it can incorporate all the things we need, namely the font awesome icons. And now you can see 67
the actual icon that we want onscreen but our column, 68
that is the child of this reusableCard, 69
it's kind of all over the place. But we can add a column property if you remember from before, something 70
called mainAxisAlignment to actually center our column in the parent. 71
So if we hit save 72
now you can see that our icon and our text will go right in the middle of the parent which is the reusable 73
Card. 74
Now we know that in the final design, we're going to have two cards that essentially look pretty much 75
the same. 76
They both have an icon and a bit of text and the styling are exactly the same. 77
So it makes sense then for us to actually reuse this part where we're creating the icon and the gap 78
and the text widget so that we can extract it as a separate widget that we'll be able to reuse anywhere 79
we wish. 80
So here's a challenge. 81
So we're going to create a custom icon content widget. And as a challenge, I want you to try and extract 82
everything that is inside our cardC,hild which is going to be repeated across two cards, into a separate 83
widget. 84
So try and remind yourself how we did it for the reusableCard and pause the video and try to complete 85
this challenge. 86
All right. 87
So in order to do this, we're going to select the highest level of the widget that we want to extract. 88
So we know we have a column with some children but it's the column that we actually want to take out 89
of the main tree and create a separate widget. As long as our cursor is selected on it, 90
then we can head over to our Flutter outline and you can see here in the main widget tree, we've got 91
the corresponding column selected as well. 92
And now all we need to do is right click on it and click on extract widget. 93
And now we get to give it a name and we can call that iconContent and we're going to refactor this 94
into a separate widget. 95
Now as I mentioned before as of the latest version of Dart, we don't need the new keyword, but we now have 96
a icon content widget. 97
And it's now extracted down into here. 98
So now the next challenge for you is we've extracted this widget but we need to be able to reuse it 99
in two places. 100
So one we've already got which is here in the iconContent, but the second place is over here in the 101
second card. Because the icon content describes a column that has a icon and a bit of text. 102
But of course the icon and text are actually different between these two cards. 103
So we need to be able to reuse that icon content widget to be able to display each of these 104
no matter what icon they have. That means you're going to have to change a little bit of code that we 105
currently have in our icon content widget. 106
The end goal is to be able to have that same icon content widget to be able to create both the male 107
icon card and the female icon card by using that custom widget that we created just now. 108
So pause the video and try to complete this challenge. So in order to achieve this we're going to do 109
exactly the same thing that we did in our custom reusableCard, 110
that is create properties to be able to use in the widget that we build. 111
So over here we're going to first remove the default constructor that came when we use that extract 112
functionality that Flutter has where we extracted our icon content, and instead we're going to create our 113
own custom constructors so that we can pass over a value for the icon and also a custom value for the 114
text. 115
So first of all, let's create our properties. 116
So again it's going to have the final keyword and we're going to see that whenever we create properties 117
for our widgets. 118
And then we're going to have a data type, 119
so in this case it's going to be icon data. 120
Now how do I know that it's going to be of icon data data type? 121
Well you can always check the icon widget and you can see that for the property called icon, 122
it's expecting a icon data type. 123
So we've got our icon data 124
and we're simply going to call it icon. 125
And now we can add our second property which is going to be a string. 126
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
we'll be able to pass over a female when we're creating the female card, and male 128
when we're creating the male card. 129
So now we're getting some errors because we have yet to initialize these final properties. 130
Remember that final variables can only have one value and that is at the point where they are created. 131
So when this icon content gets created, the part that gets triggered is of course our constructor. 132
So I'm going to create the constructor now. And the constructor is going to have some named properties 133
and it's going to have a 134
this.icon and also a this.label. 135
Now we could make it so that both of these are required but you can also just leave it as it is. 136
So now that we've created our constructor, we've created our properties, 137
It's time to actually specify where these properties are going to go in our main build method. 138
So the first thing that's going to be custom is of course our icon. 139
So it's no longer going to be hard coded as the mars icon. 140
And we're going to change also the text to the label property. 141
So whatever is passed in through this property is going to go right here. 142
That's going to be male and female. 143
And so now when we go into our BMI calculator, the main widget tree, we can update our icon content to include 144
a icon which is going to be a font 145
AwesomeIcon.mars. 146
And then there's also going to be a label which is simply going to be the word 'MALE'. 147
And that's why this expects a string. 148
So let's hit save and now let's go ahead and also do the same for our second card here. 149
So our second reusableCard is also going to have a cardChild, and the child is going to be a widget 150
that's our icon content widget. 151
And it's also going to have an icon 152
but this time, the icon is going to be the venus symbol, venus for women and the label is going to read 153
female. Cool. 154
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
and all of the styling is coming from our IconContent. 156
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
to create again. 158
Instead we're relying on our custom widget IconContent here. And we're just passing in some different 159
values for the parts which need to change, such as the actual icon and the actual label. 160
So you can see that we're kind of starting to create our own widgets rather than just relying on the 161
out-of-the-box Flutter widget. And we're able to use these properties and our constructor to be able 162
to specify some custom content for each of the widgets that we create. 163
At this point, you can see our custom widgets are starting to take up a lot of space in our main input_ 164
page.dart file. 165
Now in this case it's actually probably quite a good idea to separate out our IconContent and our reusable 166
Card in two separate Dart files. 167
And this is because we might want to use this in other files as well, maybe in other pages or screens 168
in our app. 169
So it doesn't make sense to have it all crammed into one file. 170
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
_content and then we're just going to click yes to add it to Git. And I'm going to also create 172
a new Dart file that's going to hold our reusableCard, reusable_card and it will create our 173
Dart file as well. 174
So now let's go ahead and take everything that's related to our IconContent and cut it out of the input_ 175
page.dart file and instead paste it in here. 176
And of course whenever we're using our material widgets, we always have to import the material package. 177
And we're also going to transplant our reusableCard over to our reusable_car.dart but not before 178
we import our material.dart package. 179
And now we can paste in our reusableCard. 180
Now if we take a look at our IconContent, you can see that we have a lot of things are pretty much hardcoded 181
right? Like the size of the icon or the size of the gap between the icon and the text or things such 182
as the style of the text. 183
Now it often makes sense to simply just take these parts out and create it as a constant at the top of 184
the file. 185
And this way if we think that we want to change the labelTextStyle, then we have to see it right at the 186
top here and we can update and edit it as we need to. 187
And inside here, we simply refer to labelTextStyle. And that way if we have lots of labels or needing that 188
particular style, then they can all refer to this constant. 189
So the final thing to fix in here is that we have a lot of errors because it no longer knows what reusable 190
Card is or what IconContent is because those widgets were removed from this file. 191
So in order to tell our file about those other widgets, we have to import the files that we just created. 192
So icon_content.dart and also reusable_card.dart 193
So now everything should be re-factored into separate files and it'll be much easier to work on each 194
of these components separately if we need to. 195
So just as the native Flutter widget will have their own file, 196
so for example if we hold down COMMAND or CONTROL on Windows and click on our text, and you can see we've 197
got our text.dart file which contains all the code for a text widget. 198
Similarly we have our own custom widgets in their own files. So we can reuse it across our project. 199
All right. 200
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
simply just collapse it. 202
We never really need to refer to the imports when we're creating our code. And now our main input page 203
has a widget tree that is mostly full of layout and you can more easily see at a glance what it does 204
rather than having the tree completely exploded inside here and a million lines long, 205
we have something that's quite succinct and it's quite easy to figure out what's going on at a glance. 206
In the next lesson, 207
we're going to try and change the color of our card when we click on it, because at the moment nothing 208
really happens. 209
It doesn't seem like as if I could select either of these. 210
So we're going to solve that problem in the next lesson. 211
So for all of that and more, I'll see you there.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.