Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:02,280 --> 00:00:08,490
Instead of having our column with that single child scroll view, there is another widget baked into
2
00:00:08,490 --> 00:00:16,260
Flutter that we can use to ensure that we automatically have a scrollable column or row because it's
3
00:00:16,260 --> 00:00:22,440
such a common pattern that you need multiple widgets next to each other or on top of each other or above each
4
00:00:22,440 --> 00:00:23,120
other
5
00:00:23,280 --> 00:00:28,270
and that that list should be scrollable and a column and a row by default is not scrollable.
6
00:00:28,530 --> 00:00:34,320
So of course, you could always wrap your columns and rows with single child scroll view but as I said,
7
00:00:34,320 --> 00:00:40,630
Flutter has a shortcut here. Instead of manually adding that single child scroll view,
8
00:00:40,650 --> 00:00:46,140
let's get rid of it here in the transaction list widget and instead of that, let's use instead of the
9
00:00:46,140 --> 00:00:52,730
column, a ListView widget. ListView is a widget provided by Flutter which is the end by default
10
00:00:52,740 --> 00:00:55,470
a column with a single child scroll view
11
00:00:55,470 --> 00:00:59,310
you could say. On the ListView, you can set a bunch of things,
12
00:00:59,430 --> 00:01:04,740
most of them are relatively advanced and rarely needed but you can also set a scroll direction in case
13
00:01:04,740 --> 00:01:09,630
you need a row instead of a column, a scrollable row. With that if you save it,
14
00:01:09,660 --> 00:01:19,050
now we'll have the same behavior as before, as I can quickly prove if I enter items here,
15
00:01:19,280 --> 00:01:24,300
this is a scrollable list in that container which we defined here.
16
00:01:24,320 --> 00:01:25,890
Now also important,
17
00:01:25,910 --> 00:01:31,570
if I remove that container here in my transaction list widget,
18
00:01:31,810 --> 00:01:37,340
now you see no transactions are shown and we actually get an error here.
19
00:01:37,420 --> 00:01:40,510
It's a pretty long error message and it can be complicated to read,
20
00:01:40,510 --> 00:01:46,600
in the end the problem is that the vertical viewport was given an unbounded height and this might
21
00:01:46,600 --> 00:01:52,990
sound cryptic but what it means is that ListView is in the end a widget which yes, is a column with
22
00:01:52,990 --> 00:02:00,520
a scroll view but what it means in the end is that ListView is basically a widget that has an infinite
23
00:02:00,520 --> 00:02:08,410
height. Unlike a column which takes all the height it can get on the given screen, a ListView does
24
00:02:08,410 --> 00:02:14,230
not have a fixed height, it can't have a fixed height because it's scrollable, there are items that are
25
00:02:14,230 --> 00:02:20,050
currently not on the screen and therefore, the height where all the items have to fit in in the end has
26
00:02:20,050 --> 00:02:24,700
to be infinite because it has to be larger than just the screen size,
27
00:02:24,730 --> 00:02:30,240
otherwise the items that are there and just aren't on the screen at the moment wouldn't be there, right.
28
00:02:30,280 --> 00:02:35,620
So there are items below the screen or above the screen depending on where you scrolled and these items
29
00:02:35,620 --> 00:02:37,690
are also part of the ListView.
30
00:02:37,720 --> 00:02:42,940
Therefore, its height is higher than the screen height, it's actually infinite.
31
00:02:42,940 --> 00:02:49,330
The problem with an infinite height just is, if you throw it into your page like this, Flutter doesn't
32
00:02:49,330 --> 00:02:55,660
know how to size that ListView. Of course to you as a human, it's obvious, it should take the remaining
33
00:02:55,660 --> 00:02:57,100
space here right
34
00:02:57,250 --> 00:02:58,900
but that's not how Flutter works,
35
00:02:58,900 --> 00:03:04,070
it needs clearer instructions than that. So you need to give it some constraints,
36
00:03:04,090 --> 00:03:12,070
some settings on how much height it should take and previously, with that container, we had that. If you
37
00:03:12,070 --> 00:03:16,510
have a container around your ListView, you have exactly that kind of constraint
38
00:03:16,510 --> 00:03:23,050
you need. You're telling Flutter add that ListView please and Flutter has a look at its parent and it finds
39
00:03:23,050 --> 00:03:25,210
out oh my parent has a height of 300,
40
00:03:25,230 --> 00:03:29,980
okay I will take 300 as a height for the ListView. Without that container,
41
00:03:30,160 --> 00:03:36,640
the parent here of the ListView is, since we use transaction list here in user transactions, is in the
42
00:03:36,640 --> 00:03:41,760
end that column and a column by default takes all the height it can get.
43
00:03:41,760 --> 00:03:46,990
So the problem with that of course is if we have something that takes all the height it can get and
44
00:03:46,990 --> 00:03:49,570
then we have something that has an infinite height,
45
00:03:49,630 --> 00:03:56,710
if we combine these two, we have a problem because as much as I can get and I know no limits, it's a bad
46
00:03:56,710 --> 00:03:57,940
combination.
47
00:03:57,940 --> 00:04:05,080
So here, we need some wrapper that defines a height, so that Flutter knows how big that ListView actually
48
00:04:05,080 --> 00:04:07,480
should be, how high it should be in this case.
49
00:04:07,480 --> 00:04:12,940
But with that, using a ListView is the better alternative to using a column with a single child scroll
50
00:04:12,940 --> 00:04:15,470
view because it's the end shorter
51
00:04:15,580 --> 00:04:20,230
and in addition, you get a couple of other optimizations and improvements which the ListView has baked
52
00:04:20,230 --> 00:04:22,830
in. We learned about the ListView,
53
00:04:22,990 --> 00:04:29,410
there are actually two kinds of ListViews or two ways of using it I should say. The ListView widget can
54
00:04:29,410 --> 00:04:34,930
be used as we used it, by passing a children argument to its constructor and then you have a list of
55
00:04:34,930 --> 00:04:41,950
child widgets. The alternative way of using the ListView is to use the builder constructor it offers you,
56
00:04:41,980 --> 00:04:47,410
so that's an extra constructor on the ListView class which also gives you a ListView but a ListView
57
00:04:47,440 --> 00:04:49,320
that works differently.
58
00:04:49,350 --> 00:04:51,560
Now let's first of all have a look at the left case,
59
00:04:51,670 --> 00:04:57,220
there we have our child widgets and as you learned, a ListView in the end is like a column with a single
60
00:04:57,220 --> 00:05:04,120
child scroll view around it and therefore, it's able to have more items than we have space on the screen
61
00:05:04,150 --> 00:05:10,780
because it has an infinite height or width. The ListView builder generally works similarly but there
62
00:05:10,780 --> 00:05:14,880
we have no wrapping single child scroll view in that sense
63
00:05:14,980 --> 00:05:22,410
but instead here, we have some optimizations put in place by Flutter. To be precise, the ListView builder
64
00:05:22,400 --> 00:05:26,810
in the end only renders the widgets that are visible and
65
00:05:26,830 --> 00:05:32,620
that's a difference to this scenario on the left here. With ListView where you pass your children as
66
00:05:32,620 --> 00:05:40,600
an argument, all the widgets that are part of the ListView are rendered even if they're offscreen. Now
67
00:05:40,660 --> 00:05:41,810
for short lists,
68
00:05:41,830 --> 00:05:49,300
that's no problem but for very large lists, that means that you consume a lot of memory, a lot of performance
69
00:05:49,570 --> 00:05:52,300
for items that aren't even visible
70
00:05:52,300 --> 00:05:58,540
and if you then scroll such a long list, you can have lags and bad performance because Flutter needs
71
00:05:58,540 --> 00:06:03,600
to manage all these items in memory even though you might not be seeing them right now,
72
00:06:03,670 --> 00:06:05,310
you can't interact with them right now,
73
00:06:05,350 --> 00:06:08,320
still Flutter needs to maintain them all in memory.
74
00:06:08,320 --> 00:06:13,630
The idea with the ListView builder is that Flutter actually gets rid of all the items which are currently
75
00:06:13,630 --> 00:06:16,480
not visible and only shows you what's visible.
76
00:06:16,480 --> 00:06:21,970
So the parts that are not on the screen are not loaded or not rendered to be precise
77
00:06:21,970 --> 00:06:27,820
and this therefore is the solution and the approach you should use for very long lists or for lists
78
00:06:27,820 --> 00:06:33,130
where you don't know how many items will be on it, so that for longer lists, you don't run into performance
79
00:06:33,130 --> 00:06:34,610
issues and lags.
80
00:06:34,630 --> 00:06:39,580
Now it is worth noting that the ListView builder of course has a certain threshold, so it doesn't instantly
81
00:06:39,580 --> 00:06:42,010
remove every item that's not on the screen anymore,
82
00:06:42,100 --> 00:06:47,410
it waits until this is a little distance away, so until you scroll a bit before it actually removes
83
00:06:47,410 --> 00:06:53,530
that and the ListView on the left here where you pass children will actually also get rid of elements
84
00:06:53,530 --> 00:06:57,980
that are outside of the current viewport or beyond a certain threshold
85
00:06:58,060 --> 00:07:04,330
but unlike ListView builder on the right, it has less optimizations in place and unlike ListView builder,
86
00:07:04,360 --> 00:07:10,050
it actually does create all items that are in it, initially it does not create them lazily when they're
87
00:07:10,060 --> 00:07:15,820
needed but instead it just has a limited amount of optimization. So you don't want to use that for very
88
00:07:15,820 --> 00:07:20,650
long lists or lists where you don't know in advance how many items you'll have and potentially you might
89
00:07:20,650 --> 00:07:21,330
have a lot,
90
00:07:21,460 --> 00:07:25,520
in such cases you might want to use ListView builder instead to improve performance.
91
00:07:25,690 --> 00:07:30,850
So let's have a look at that ListView builder then. We can easily transform our existing list to such
92
00:07:30,850 --> 00:07:35,650
a dynamically loaded and rendered list by using ListView builder instead of ListView
93
00:07:35,830 --> 00:07:38,740
but now we need to pass different arguments here.
94
00:07:38,740 --> 00:07:45,760
The builder method requires an item builder argument, that's a must have, you must provide the item builder.
95
00:07:46,390 --> 00:07:53,680
Now item builder in turn takes a function that will give us a context,
96
00:07:53,680 --> 00:07:57,100
we get that automatically, Flutter manages that for us,
97
00:07:57,100 --> 00:08:01,550
context is this meta object with which we haven't really worked thus far
98
00:08:01,630 --> 00:08:07,110
which holds information about the position of the widget in the widget tree and int,
99
00:08:07,150 --> 00:08:14,710
it gives us a number of type int and that actually will be the index of the item we're currently building
100
00:08:14,710 --> 00:08:17,650
but step-by-step. Item builder takes a function,
101
00:08:17,650 --> 00:08:22,500
so you need to provide a function here, either a named function or as I'm doing it here,
102
00:08:22,540 --> 00:08:28,540
an anonymous function. Then this function as I just mentioned receives a context and I will name this
103
00:08:28,600 --> 00:08:34,300
ctx, you can give this any name you want but the value of this argument will be build context because
104
00:08:34,330 --> 00:08:36,790
this function here is not called by you,
105
00:08:36,820 --> 00:08:39,710
so it's not your job to provide these arguments,
106
00:08:39,760 --> 00:08:46,570
it's called by Flutter because it calls this builder function here for every new item it wants to render
107
00:08:46,570 --> 00:08:51,460
on the screen, for every new list item in the end and it gives us a context which we don't need here
108
00:08:51,460 --> 00:08:55,810
but still we get it and it gives us an index of that item.
109
00:08:55,810 --> 00:09:00,160
So is it the first item, the second item, the third item of the items it should render,
110
00:09:00,160 --> 00:09:02,380
that's what we get here.
111
00:09:02,560 --> 00:09:08,420
Now what you can't provide to the builder constructor is your children thing here,
112
00:09:08,710 --> 00:09:16,510
instead what you need to provide is the item count argument and that defines how many items should be
113
00:09:16,510 --> 00:09:17,440
built.
114
00:09:17,440 --> 00:09:20,580
In our case here, that would be the length of our transactions list,
115
00:09:20,590 --> 00:09:23,660
if we have two transactions, we want to build two items, right?
116
00:09:23,710 --> 00:09:30,910
So we pass transactions.length which gives us the number of items in our transactions list.
117
00:09:30,910 --> 00:09:35,620
Now Flutter knows that it should execute this function here twice
118
00:09:35,680 --> 00:09:42,220
if we have two items or as often as we have items in transactions and now in here, we have to return
119
00:09:42,220 --> 00:09:46,080
a widget, a widget that is built for this item
120
00:09:46,090 --> 00:09:47,890
we're currently looking at,
121
00:09:47,890 --> 00:09:54,970
so a widget that is built for the first item, for the second item and the third item and so on. The item
122
00:09:54,970 --> 00:09:59,650
I want to build here of course is my card here, so I can actually grab this entire return statement
123
00:09:59,650 --> 00:10:08,440
here all the way up here and replace this return statement with it, so that I return my card inside of
124
00:10:08,440 --> 00:10:10,070
that builder method
125
00:10:10,080 --> 00:10:14,630
here. The problem now just is in there,
126
00:10:14,640 --> 00:10:21,510
I previously got my transaction because previously, we mapped our list of transactions to a list of widgets.
127
00:10:21,570 --> 00:10:27,960
This approach does now not work anymore because now the builder instead simply takes a number of items,
128
00:10:28,170 --> 00:10:29,240
not the list itself,
129
00:10:29,250 --> 00:10:32,180
just a number of items and then repeats this function here,
130
00:10:32,190 --> 00:10:39,590
this builder function for every item. In order to now get access to the different transactions,
131
00:10:39,630 --> 00:10:47,220
we can simply replace tx here with transactions which is our overall transactions list and there with
132
00:10:47,220 --> 00:10:51,200
the square bracket syntax, we can access a specific index
133
00:10:51,240 --> 00:10:57,670
and here it's convenient and of course not a surprise and not happening by accident,
134
00:10:57,720 --> 00:11:02,480
that Flutter gives us the index as a second argument in this function
135
00:11:02,520 --> 00:11:04,830
it calls for the item it tries to create.
136
00:11:04,980 --> 00:11:10,650
So it gives us zero for the first element it tries to create, one for the second element and so on and
137
00:11:10,650 --> 00:11:16,400
therefore we can use this index here to access the first transaction, the second transaction and so on
138
00:11:16,410 --> 00:11:18,120
depending on which item is getting built
139
00:11:18,120 --> 00:11:20,440
and this is all managed by Flutter.
140
00:11:20,550 --> 00:11:25,180
So now we use transactions index instead of tx here
141
00:11:25,390 --> 00:11:29,680
and with that, if we save this, we get our transactions here
142
00:11:29,680 --> 00:11:34,870
but now built with the help of the builder and that of course is pretty nice because now, here of course
143
00:11:34,870 --> 00:11:40,240
we don't really see that or feel that but now we have a list that also has a great performance for
144
00:11:40,240 --> 00:11:41,400
a lot of items,
145
00:11:41,410 --> 00:11:46,870
so now this is the solution you should use for very long lists. For lists where you know how many items
146
00:11:46,870 --> 00:11:53,350
you have and it'll only be six or seven, then using ListView children is perfectly fine but for long lists
147
00:11:53,410 --> 00:11:56,350
or lists where you don't know in advance how many items you'll have,
148
00:11:56,380 --> 00:11:59,860
consider using ListView builder to get the best possible performance.
17114
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.