Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
0
1
00:00:00,390 --> 00:00:00,750
All right.
1
2
00:00:00,780 --> 00:00:06,390
So now that we're all set up and ready to go, we're going to get started designing the user interface
2
3
00:00:06,450 --> 00:00:08,040
of our app.
3
4
00:00:08,100 --> 00:00:14,310
Our app is going to have two images that are in a row, horizontally next to each other.
4
5
00:00:14,910 --> 00:00:20,130
And as with every sort of Flutter app design, we're going to be using a lot of widgets to achieve this.
5
6
00:00:21,100 --> 00:00:21,690
By now,
6
7
00:00:21,700 --> 00:00:26,140
you're already pretty familiar with scaffolds and rows, because we've really done it.
7
8
00:00:26,260 --> 00:00:29,460
And the design of this app should be quite familiar to you.
8
9
00:00:29,470 --> 00:00:33,520
We're going to start off, as with all of our apps, with a scaffold,
9
10
00:00:33,520 --> 00:00:36,080
and in this scaffold we're going to have an app.
10
11
00:00:36,420 --> 00:00:43,120
But for the body of the scaffold, we're simply going to have a rope with two images each containing a
11
12
00:00:43,120 --> 00:00:45,750
picture of a dice image.
12
13
00:00:45,790 --> 00:00:49,570
Now that we've got an overview of what the user interface should look like,
13
14
00:00:49,570 --> 00:00:56,440
let's go ahead and build it inside Android Studio. Now notice that the app bar is already set out for
14
15
00:00:56,440 --> 00:00:56,710
you.
15
16
00:00:56,740 --> 00:01:03,010
So we don't need to touch that. And the body is simply a stateless widget, similar to ones that we've
16
17
00:01:03,010 --> 00:01:09,610
created before which gives us this crucial build method, which will refresh itself every single time
17
18
00:01:09,670 --> 00:01:13,330
we hit save, or when we click on the hot reload button.
18
19
00:01:13,330 --> 00:01:16,890
So is gonna make designing our app a lot easier.
19
20
00:01:16,960 --> 00:01:22,480
Currently, our body is a dice page which only returns a container.
20
21
00:01:22,480 --> 00:01:29,290
So that means that there's actually absolutely nothing on screen so far, because the container is pretty
21
22
00:01:29,290 --> 00:01:30,790
much invisible.
22
23
00:01:30,790 --> 00:01:34,150
Let's go ahead and return a row instead.
23
24
00:01:34,150 --> 00:01:42,850
Now our row is going to have two children. And the two children are going to be two image widgets. The
24
25
00:01:42,850 --> 00:01:48,400
image widget that we've been working with so far is something that looks like this.
25
26
00:01:48,670 --> 00:01:52,810
We create an image, and we specify what kind of image we want to use.
26
27
00:01:53,320 --> 00:01:59,780
And in this case of course we want to use an asset image, pulling in the images from our images folder.
27
28
00:01:59,890 --> 00:02:05,590
Now because we've already got everything linked up inside our config file, we'll be able to tap into
28
29
00:02:05,600 --> 00:02:11,620
to any of the images inside this folder, just by specifying the path to that image.
29
30
00:02:11,620 --> 00:02:17,620
So in this case, the asset name is going to be a string inside some single quotes, and then it's images
30
31
00:02:17,950 --> 00:02:21,700
/dice1.png
31
32
00:02:21,940 --> 00:02:26,490
And as soon as I hit save, you'll see my dice show up on screen.
32
33
00:02:27,280 --> 00:02:29,560
But there's a bit of a problem here.
33
34
00:02:29,770 --> 00:02:34,390
Our dice the image is actually too big to fit onto the screen.
34
35
00:02:34,390 --> 00:02:40,180
And we're seeing these yellow and black bars telling us that there's actually parts of the image that's
35
36
00:02:40,180 --> 00:02:42,420
gone off the screen.
36
37
00:02:42,860 --> 00:02:51,050
So as we know, the user interface of Flutter apps are painted onto the screen, on both iOS and Android.
37
38
00:02:51,050 --> 00:02:57,200
So that means if you tell the app to paint something that's really really large, and it's going to go
38
39
00:02:57,320 --> 00:03:03,140
off the screen on one side or multiple sides of the screen, then you're going to end up with these hatched
39
40
00:03:03,290 --> 00:03:05,720
yellow and black bars.
40
41
00:03:05,750 --> 00:03:08,240
So how can we solve this problem?
41
42
00:03:08,240 --> 00:03:13,670
How can we get rid of these ugly yellow and black bars and make sure that all of the content we want
42
43
00:03:13,670 --> 00:03:17,400
to show on the screen, actually fits on the screen?
43
44
00:03:17,450 --> 00:03:23,870
First things first, I'm going to remember to add my commas after every parentheses, so that when I hit
44
45
00:03:23,870 --> 00:03:30,470
save, Dart will automatically reformat it for me, and it looks far less confusing what's going on.
45
46
00:03:30,590 --> 00:03:37,940
So we know that we've got a row with a single child at the moment, which is just an image widget, and
46
47
00:03:37,940 --> 00:03:45,090
the image that's being displayed in that widget is an asset image and it comes from this file here.
47
48
00:03:45,110 --> 00:03:48,640
Now this file, if you double click on it, is quite large.
48
49
00:03:48,680 --> 00:03:52,630
It's actually 500 by 500 pixels large.
49
50
00:03:52,640 --> 00:03:58,940
Now when that gets rendered on screen, normally you only have a width of about 300 and that's why it's
50
51
00:03:58,940 --> 00:04:00,970
gone off the screen to the right.
51
52
00:04:01,130 --> 00:04:04,280
There's a couple of ways that we can sort this out.
52
53
00:04:04,400 --> 00:04:12,380
We can either change our images width property, so we can say that the width of this image should only
53
54
00:04:12,380 --> 00:04:14,850
be 200 pixels.
54
55
00:04:14,870 --> 00:04:18,720
So now, the image widget is only 200 pixels wide.
55
56
00:04:18,860 --> 00:04:23,390
And that means our whole image can actually fit into the screen.
56
57
00:04:23,390 --> 00:04:26,910
But the problem with this is, this is kind of hard coded right?
57
58
00:04:27,020 --> 00:04:33,650
Say if we had a much smaller phone or say if the user turned their phone to landscape, then that kind
58
59
00:04:33,650 --> 00:04:35,960
of layout doesn't really look great.
59
60
00:04:35,960 --> 00:04:42,430
It's all the way bunched up to the left corner, and it's not taking up as much space as it could do.
60
61
00:04:42,530 --> 00:04:46,170
And it's really not making the most of the screen real estate.
61
62
00:04:46,280 --> 00:04:50,100
So what can we do about this?
62
63
00:04:50,100 --> 00:04:56,940
Well, one of the most useful widgets that we can use to sort out this problem is something called expanded.
63
64
00:04:57,690 --> 00:05:06,880
An expanded class has to be a child of a row or a column. And what it does, is that it will expand to
64
65
00:05:06,880 --> 00:05:09,680
fill the available space in the main axis.
65
66
00:05:09,700 --> 00:05:14,840
So that means that for a row, it'll try to fill as much horizontal space as it has,
66
67
00:05:14,840 --> 00:05:18,740
and for a column, it'll try to be as tall as it can be.
67
68
00:05:18,760 --> 00:05:24,220
So that means any children that you put into this widget will also expand and contract, depending on
68
69
00:05:24,220 --> 00:05:28,680
how much space is available. Let's test this out in real life.
69
70
00:05:28,680 --> 00:05:34,530
Let's delete that width property, so that we're no longer hard coding how our layout looks.
70
71
00:05:34,590 --> 00:05:42,850
But let's make it adaptable, by embedding our image widget inside an expanded widget. So I'm going to
71
72
00:05:42,850 --> 00:05:44,620
cut out my image widget.
72
73
00:05:44,620 --> 00:05:52,030
I'm going to put it down at the bottom, and instead of it, I'm going to add my expanded widget. And inside
73
74
00:05:52,060 --> 00:05:58,540
this widget, it can only have a single child and that child is of course going to be our image widget
74
75
00:05:58,720 --> 00:06:00,580
that we got from earlier on.
75
76
00:06:00,580 --> 00:06:06,430
And I'm going to delete that extra comma, and now if I hit save, you'll notice that the expanded widget
76
77
00:06:06,940 --> 00:06:13,550
automatically resizes to fill the available horizontal space, because we're inside a row.
77
78
00:06:13,720 --> 00:06:20,800
Now if I changed that to a column, then you'll notice that it'll try to expand to fill the entire vertical
78
79
00:06:20,800 --> 00:06:24,930
space. But we want to dice side by side.
79
80
00:06:24,980 --> 00:06:31,610
So we're going to change this back to a row, and we're going to have our expanded widget making sure
80
81
00:06:31,610 --> 00:06:39,720
that our image doesn't go off the screen, but takes up as much space as it can on the screen. The other
81
82
00:06:39,720 --> 00:06:46,920
thing that you can do with an expanded widget is you can specify how much space it should take up compared
82
83
00:06:46,920 --> 00:06:49,400
to other expanded widgets.
83
84
00:06:49,410 --> 00:06:56,820
I'm gonna go ahead and copy this expanded widget, and I'm going to paste it into my row.
84
85
00:06:56,850 --> 00:06:59,990
So I now have a row with two expanded widgets.
85
86
00:07:00,600 --> 00:07:07,170
And as soon as I hit save, you can see that the both of them will try to take up as much space as it
86
87
00:07:07,170 --> 00:07:10,300
can on the horizontal axis.
87
88
00:07:10,560 --> 00:07:15,060
And because I have two expanded widgets, they only have half of the screen each.
88
89
00:07:15,060 --> 00:07:17,550
So that's how much they each get.
89
90
00:07:17,550 --> 00:07:23,780
But let's say that I wanted the one on the left to take up twice as much width as the one on the right.
90
91
00:07:23,850 --> 00:07:31,230
I can do that really easily by simply adding a property called flex to my expanded widget. So I can say
91
92
00:07:31,230 --> 00:07:32,630
that the one on the left,
92
93
00:07:32,670 --> 00:07:38,190
so at the beginning of the row, it's gonna have a flex of two. And the one on the right is going to have
93
94
00:07:38,190 --> 00:07:40,190
a flex of one.
94
95
00:07:40,200 --> 00:07:48,930
What this does, is that it ensures that this expanded widget, expands to take up twice the width that
95
96
00:07:49,170 --> 00:07:50,380
this one will do.
96
97
00:07:50,520 --> 00:07:55,860
But still maintaining that everything is inside the space that's available in the screen.
97
98
00:07:55,860 --> 00:08:00,320
So when I hit save, you'll see that this one becomes twice as wide,
98
99
00:08:00,420 --> 00:08:04,200
and this one becomes only half as wide as this one.
99
100
00:08:04,290 --> 00:08:07,560
So flex is really flexible.
100
101
00:08:07,560 --> 00:08:12,180
You could say that. You could change the number to any ratio you want.
101
102
00:08:12,180 --> 00:08:18,210
So you could turn this into 12 and you can change this into 5 if you wanted a ratio of 12 :
102
103
00:08:18,210 --> 00:08:19,150
5.
103
104
00:08:19,440 --> 00:08:26,130
And it means that you have a really adaptable way of switching up the sizes of all your widgets that
104
105
00:08:26,130 --> 00:08:32,760
you put on the screen. But in our case, we actually don't need the flex widget because we want both of
105
106
00:08:32,760 --> 00:08:35,780
them to take up the same amount of space.
106
107
00:08:35,970 --> 00:08:41,990
And by default, every expanded widget gets its flex setting, set to 1.
107
108
00:08:42,030 --> 00:08:46,050
And of course if they both have a flex of one, then it looks exactly like this.
108
109
00:08:46,050 --> 00:08:48,470
They take up the same amount of space.
109
110
00:08:48,600 --> 00:08:52,730
So this is already included in the expanded widget.
110
111
00:08:52,750 --> 00:08:54,430
Now how do I know this?
111
112
00:08:54,460 --> 00:08:57,050
Of course, it's the documentation.
112
113
00:08:57,190 --> 00:09:04,150
Documentation is our friend. And as developers we might not have a lot of friends, but the documentation
113
114
00:09:04,180 --> 00:09:06,040
is definitely one of them.
114
115
00:09:06,490 --> 00:09:12,830
So if we scroll down, you'll notice that we have a lot of other properties that we can change.
115
116
00:09:12,940 --> 00:09:18,070
But the most commonly ones that you'll be using when you're using this expanded class, is going to be
116
117
00:09:18,160 --> 00:09:24,760
the flex. And if you come from Web Development and you've used Bootstrap, then this will be a really natural
117
118
00:09:24,760 --> 00:09:26,440
concept to grasp.
118
119
00:09:26,470 --> 00:09:29,440
Now if you've never done any Web Development, then don't worry.
119
120
00:09:29,470 --> 00:09:31,270
It's really really simple.
120
121
00:09:31,330 --> 00:09:37,330
The flex property is just a ratio. And once you have a play around with it, you'll understand it with
121
122
00:09:37,330 --> 00:09:38,960
no problems.
122
123
00:09:38,980 --> 00:09:46,660
Now that I've got both of my dice images onto the screen as a image widget, that has the image inside
123
124
00:09:46,660 --> 00:09:51,870
it set to an asset image, I want to show you a slightly shorter way of doing this.
124
125
00:09:52,150 --> 00:09:58,270
And the reason why I know this is because I went onto the widget catalog, and I had a look at the asset
125
126
00:09:58,300 --> 00:10:06,220
images and icon widgets, and I selected the image widget that we're using. And it says here that there's
126
127
00:10:06,280 --> 00:10:14,530
several convenient constructors to create an image. And we've been using simply a bog standard image
127
128
00:10:14,620 --> 00:10:21,250
and then specifying the image property for it, using this image provider thing which can be an asset
128
129
00:10:21,280 --> 00:10:26,920
image or network image. But actually, because you do this so often, the flutter team actually gave you
129
130
00:10:26,920 --> 00:10:33,070
a very very simple factory method, which is image.asset or image.network.
130
131
00:10:33,070 --> 00:10:39,820
So we can transform our code to make it a lot shorter by using this constructor instead.
131
132
00:10:40,000 --> 00:10:47,710
Let's go over to our Android Studio. And instead of writing out all of this image code, I can simply write
132
133
00:10:47,950 --> 00:10:59,930
image.asset and then specify the asset name, which is images/dice1.png. And that does exactly
133
134
00:10:59,930 --> 00:11:05,700
the same as this, but it looks a lot shorter because using asset images is so common
134
135
00:11:05,720 --> 00:11:10,240
they've added in a convenient way of creating this image widget.
135
136
00:11:11,030 --> 00:11:18,680
So let's go ahead and transform this second image widget in the same way. And you can see now, our code
136
137
00:11:18,740 --> 00:11:25,730
is a lot more concise. And that means there's less nesting and there's less potential issues that could
137
138
00:11:25,730 --> 00:11:28,070
crop up. When you hit save,
138
139
00:11:28,070 --> 00:11:34,940
nothing will change because it's still pulling in our image from our assets, and it's still displaying
139
140
00:11:34,940 --> 00:11:35,600
it in a row.
140
141
00:11:36,660 --> 00:11:44,070
Now in this lesson and in previous lessons, we've been moving widgets around by copying and pasting or
141
142
00:11:44,070 --> 00:11:46,330
cutting it out and moving it around.
142
143
00:11:46,490 --> 00:11:48,010
And that's quite error prone.
143
144
00:11:48,060 --> 00:11:54,510
So in the next lesson, I want to show you a really convenient way of embedding a widget inside another
144
145
00:11:54,510 --> 00:12:00,720
widget or deleting a widget if you need to. For all of that and more, I'll see on the next lesson.
16488
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.