Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:02,380 --> 00:00:07,150
We had a look at some of the widgets we can use and at the widget catalog and of course throughout the course,
2
00:00:07,150 --> 00:00:10,190
we'll use loads of the widgets you saw there,
3
00:00:10,210 --> 00:00:17,770
so no need to learn it by heart right now. For the moment however, I want to move on by now also moving
4
00:00:17,770 --> 00:00:23,500
my buttons here, my answer buttons into a separate widget, into a custom widget.
5
00:00:23,500 --> 00:00:30,480
Maybe change the styling a little bit, maybe to give them a blue background and make them take the full
6
00:00:30,500 --> 00:00:34,510
available width but that won't be the the focus here,
7
00:00:34,510 --> 00:00:36,750
instead what I want to make sure is that
8
00:00:36,760 --> 00:00:44,470
we have real text on these buttons, so that we have text that fits to the question we have here,
9
00:00:44,470 --> 00:00:50,920
so that we continue working on this first basic application. And for this, let's create a new answer.dart
10
00:00:50,950 --> 00:00:54,160
file which should hold the answer widget
11
00:00:54,160 --> 00:00:56,150
and there we need to create a widget now.
12
00:00:56,220 --> 00:00:59,800
Now you could think that you need to create a stateful widget now,
13
00:00:59,890 --> 00:01:00,380
right
14
00:01:00,430 --> 00:01:07,240
because here in main.dart, on a button we of course have that onPressed argument to which we pass a
15
00:01:07,240 --> 00:01:10,270
pointer to the answer question function.
16
00:01:10,270 --> 00:01:18,550
Now just because we register a function here for an event does not mean that the RaisedButton has to
17
00:01:18,550 --> 00:01:20,200
be in a stateful widget.
18
00:01:20,230 --> 00:01:26,230
Of course we want to change some data when this event fires, when the user presses the button
19
00:01:26,230 --> 00:01:34,450
but as it turns out, we can also trigger a function in another place of the app even if this button lives
20
00:01:34,450 --> 00:01:35,920
in a separate widget
21
00:01:35,920 --> 00:01:41,980
and that is a core concept and a core pattern which you will use a lot in Flutter and therefore it's exactly
22
00:01:41,980 --> 00:01:44,410
the pattern we'll dive in right now.
23
00:01:44,410 --> 00:01:50,530
So here in the answer.dart file, I'll create a new stateless widget here actually and I will name
24
00:01:50,530 --> 00:01:51,470
it answer
25
00:01:51,820 --> 00:01:59,710
and just as in the question widget, we need to import the material file from the Flutter package because
26
00:01:59,710 --> 00:02:02,720
that unlocks stateless widget and so on.
27
00:02:02,760 --> 00:02:07,810
Now in here, I will leave the container because as a child of that container, I want to have my button
28
00:02:08,110 --> 00:02:12,030
and I keep the container because that will allow me to control the width.
29
00:02:12,100 --> 00:02:15,780
So here, the child is the RaisedButton here,
30
00:02:15,910 --> 00:02:18,970
the text will soon be received from outside
31
00:02:19,000 --> 00:02:26,380
and I'll come back to that and onPressed as I said should change something but will also make that
32
00:02:26,380 --> 00:02:32,220
change in another widget and how that works is also something I'll show you in a second.
33
00:02:32,230 --> 00:02:38,650
First of all, let's adjust the width and I'll set it to double infinity again, which is a helper property
34
00:02:38,660 --> 00:02:40,400
on the double object.
35
00:02:40,480 --> 00:02:43,180
Remember, everything in Dart is an object,
36
00:02:43,180 --> 00:02:49,480
so are doubles and that is the core double type which at the same time is basically the class
37
00:02:49,720 --> 00:02:52,070
for the double value you could say
38
00:02:52,540 --> 00:02:58,900
and on this class we have an infinity property which basically gives us a value which tells the container
39
00:02:58,900 --> 00:03:03,460
to take as much width as it can get, which is the width of our device.
40
00:03:03,460 --> 00:03:05,170
So that's the width of the container,
41
00:03:05,170 --> 00:03:11,830
now for onPressed I'll temporarily use null again so that we don't get an error and that we now can
42
00:03:11,830 --> 00:03:13,840
use this button as it is.
43
00:03:13,840 --> 00:03:21,790
I also want to set the color of the button here and I will set it to a color by accessing colors and
44
00:03:21,790 --> 00:03:28,330
colors actually is a class which also has some so-called static properties,
45
00:03:28,420 --> 00:03:34,760
these are properties which you can directly use on the class itself without instantiating it first
46
00:03:34,810 --> 00:03:40,010
and there you have various preconfigured colors and I will simply use blue.
47
00:03:40,030 --> 00:03:45,610
Now this can look strange because we haven't used that before, a static property in the end simply as
48
00:03:45,610 --> 00:03:50,080
I said is a property which you can use without instantiating class.
49
00:03:50,080 --> 00:03:58,310
If we have a look at the source code here, we see that the class here has these static const values, const
50
00:03:58,350 --> 00:03:59,850
is something we haven't seen before,
51
00:03:59,860 --> 00:04:06,730
let's ignore it for now, these static const values here, like black and then a different shade of black
52
00:04:06,760 --> 00:04:07,810
and so on
53
00:04:08,050 --> 00:04:11,600
and then if we scroll down, also different shades of white.
54
00:04:11,620 --> 00:04:15,610
So these are simply properties, normal properties on the class,
55
00:04:15,610 --> 00:04:20,990
the only difference is that you can access them without creating an instance of the class first and
56
00:04:21,010 --> 00:04:26,190
such properties exist because we need that value here, right
57
00:04:26,200 --> 00:04:28,530
and therefore, this is like a utility feature of Dart
58
00:04:28,540 --> 00:04:35,110
you could say, that we can get easy access to such a value without having to create a new instance. Instances
59
00:04:35,110 --> 00:04:40,090
of classes typically makes sense if you want to create multiple different objects based on one and the
60
00:04:40,090 --> 00:04:41,220
same class.
61
00:04:41,320 --> 00:04:46,600
Here of course we want to have multiple different colors but each color is just a value, like a
62
00:04:46,600 --> 00:04:51,490
simple text or so on and therefore of course technically, it's also an object but we don't need
63
00:04:51,490 --> 00:04:54,520
the complex colors object for that. Colors in
64
00:04:54,530 --> 00:04:58,230
the end is just like a group of predefined single colors
65
00:04:58,240 --> 00:05:05,670
you could say, so this colors class here exists not to be instantiated because colors itself, this object,
66
00:05:05,670 --> 00:05:12,450
that doesn't do anything, it just exists as a grouping mechanism around preconfigured values. A little
67
00:05:12,450 --> 00:05:19,650
bit like an enum but an enum simply gives numbers 0, 1, 2, a label, a human readable label. Here, the idea
68
00:05:19,650 --> 00:05:25,770
is to have a human readable label for a more complex value you could say because the value here is not
69
00:05:25,770 --> 00:05:34,080
just a number but actually the hex code or the binary representation of a color.
70
00:05:34,080 --> 00:05:39,750
So that is what we're doing here, we're getting access to this static property here on the colors class
71
00:05:40,170 --> 00:05:47,030
and this will give us the internal color value which Dart and Flutter can use to color this button
72
00:05:47,220 --> 00:05:51,410
and with all of that, we can use the answer widget here in the main.dart file. For that,
73
00:05:51,420 --> 00:05:52,920
let's first of all add an import,
74
00:05:52,920 --> 00:05:57,690
you always need to import what you want to use in a file because since the answer widget lives in a
75
00:05:57,690 --> 00:06:02,950
different file, in order to use it in the main.dart file, we have to import it there
76
00:06:02,970 --> 00:06:08,240
and then with it imported, we can replace our RaisedButton here with answer
77
00:06:08,250 --> 00:06:15,090
and now here of course we create concrete instances of our answer widget class because we want to create
78
00:06:15,300 --> 00:06:20,910
widget objects, multiple different widget objects, which we can use here
79
00:06:20,910 --> 00:06:24,420
and that should be an answer not answers here.
80
00:06:24,440 --> 00:06:29,360
Now with that if we save this, we now have our buttons there. Now
81
00:06:29,370 --> 00:06:36,270
they are greyed out because at the moment, they're all locked, disabled because I haven't assigned a real
82
00:06:36,270 --> 00:06:39,980
function to onPressed and that will be the next step and here,
83
00:06:40,020 --> 00:06:46,410
the tricky thing will be that this function which I want to assign here actually lives in the main.dart
84
00:06:46,410 --> 00:06:52,740
file because that is where I manage my question index and I have to manage the question index there because
85
00:06:52,740 --> 00:06:57,600
I also have my questions in here and I need to have my questions in here because I want to pass them
86
00:06:57,600 --> 00:07:04,020
down to the question widget which has no direct connection to the answer widget. So we can't manage the
87
00:07:04,020 --> 00:07:09,980
question index in the answer widget because if we would do that, then we would have the value in here
88
00:07:09,990 --> 00:07:14,970
but then again we couldn't use it to select a question here which we want to forward to the question
89
00:07:14,970 --> 00:07:15,890
widget.
90
00:07:15,930 --> 00:07:22,950
So our main.dart file is the common denominator you could say, the shared widget between the answer and
91
00:07:22,950 --> 00:07:28,500
the question widget because our main.dart file and the widget in there, the MyApp widget, that is the
92
00:07:28,500 --> 00:07:35,970
parent widget of question and answer, it is the widget that instantiates and uses question and answer
93
00:07:36,330 --> 00:07:42,270
and therefore we want to manage our state which both components need or which both widgets need, we want
94
00:07:42,270 --> 00:07:48,780
to manage that state here in the MyApp component or in MyApp widget and therefore also in MyAppState
95
00:07:48,870 --> 00:07:50,640
which is connected to that widget.
96
00:07:50,700 --> 00:07:58,080
This concept is called lifting the state up, you manage the state on the shared, on the common denominator
97
00:07:58,350 --> 00:08:05,130
of the different widgets that need this state and that is the direct parent of these widgets that need
98
00:08:05,130 --> 00:08:06,370
the state.
99
00:08:06,420 --> 00:08:12,140
So since we manage the state in here, we also have the function to change the state in here, in the MyAppState
100
00:08:12,170 --> 00:08:12,920
class
101
00:08:13,020 --> 00:08:20,030
but how do we now get access to the answer question function in our answer widgets here?
102
00:08:20,160 --> 00:08:27,870
The answer is pretty simple. Just as we can pass text to a widget, we can also pass a pointer at a
103
00:08:27,870 --> 00:08:28,880
function to a widget.
104
00:08:29,490 --> 00:08:31,500
So answer question,
105
00:08:31,500 --> 00:08:38,190
my function here can be forwarded to the answer widgets, without parentheses because I don't want to
106
00:08:38,190 --> 00:08:42,550
execute my answer question function immediately when Dart reads this,
107
00:08:42,660 --> 00:08:49,850
instead I want to forward the pointer at this function to my answer widget. And now in the answer widget,
108
00:08:49,910 --> 00:08:55,350
we of course need to accept this as our argument to the constructor because the answer widget here, that
109
00:08:55,350 --> 00:08:56,950
in the end is just a class right and
110
00:08:56,970 --> 00:08:59,200
therefore it can have a constructor.
111
00:08:59,250 --> 00:09:05,130
So here, we can add a constructor by repeating the class name and I'll use that shortcut for the constructor
112
00:09:05,700 --> 00:09:08,740
and I will also add a property here,
113
00:09:08,910 --> 00:09:15,410
a final property, the type now is function which is built into Dart and as the name suggests,
114
00:09:15,450 --> 00:09:21,150
this means that the values stored in this property has to be a function or a pointer at a function
115
00:09:21,150 --> 00:09:22,340
to be precise
116
00:09:22,440 --> 00:09:29,950
and therefore here now, you can give this any name you want, I'll name this selectHandler, whatever you
117
00:09:29,950 --> 00:09:31,060
want to name it
118
00:09:33,960 --> 00:09:38,880
and in my answer constructor, I now store whatever I get here in selectHandler.
119
00:09:38,940 --> 00:09:40,280
Now what I do get in here
120
00:09:40,320 --> 00:09:46,710
in my answer constructor is a pointer at the answer question and this pointer is stored in this property.
121
00:09:46,710 --> 00:09:53,160
in my answer class and function simply means that what is stored here has to be a pointer at a function.
122
00:09:53,160 --> 00:09:59,100
And now since we have that pointer at a function, which is exactly what I need down there, I can use select
123
00:09:59,100 --> 00:10:05,490
handler here. Again, without parentheses because the same thing as explained earlier still applies,
124
00:10:05,490 --> 00:10:10,470
we don't want to execute this immediately and hence now we should have a setup where we can trigger
125
00:10:10,470 --> 00:10:16,920
a function that's actually defined in a different widget from inside our answer widget because we pass
126
00:10:16,920 --> 00:10:25,560
a reference to that function down to the answer widget here in our MyAppState. So with this set up,
127
00:10:26,510 --> 00:10:28,360
we should be able to save this
128
00:10:28,550 --> 00:10:33,800
and now if I press a button here, indeed our text here changes, which means that this communication
129
00:10:34,070 --> 00:10:35,900
between parent and child works.
14656
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.