1 00:00:05,400 --> 00:00:07,000 So in this video, we're going to have a look at 2 00:00:07,000 --> 00:00:09,880 using a ListView to display something 3 00:00:09,880 --> 00:00:12,880 a bit more complex than just a single text widget. 4 00:00:12,880 --> 00:00:15,200 Now you can of course, display any other values 5 00:00:15,200 --> 00:00:17,790 from the XML that you want but I've chosen to show 6 00:00:17,790 --> 00:00:22,190 the name of the application, the artist and the summary. 7 00:00:22,190 --> 00:00:23,393 So here's the challenge. 8 00:00:24,360 --> 00:00:26,740 You wanna create a ConstraintLayout containing 9 00:00:26,740 --> 00:00:30,420 three TextView widgets, arranged one below the other 10 00:00:30,420 --> 00:00:33,250 so that they match the image you can see on screen. 11 00:00:33,250 --> 00:00:35,733 You wanna call the layout list_record. 12 00:00:36,723 --> 00:00:40,060 Now the TextViews should have the IDs tvName, 13 00:00:40,060 --> 00:00:44,860 tvArtist and tvSummary with the appropriate capitalization 14 00:00:44,860 --> 00:00:48,840 and all three should grow in height to match their contents. 15 00:00:48,840 --> 00:00:52,420 Now the artist TextView should also be able to grow wider 16 00:00:52,420 --> 00:00:56,620 if necessary, to accommodate longer artist names. 17 00:00:56,620 --> 00:00:59,090 So you wanna make sure that all the necessary constraints 18 00:00:59,090 --> 00:01:01,520 are created so that the widgets will appear 19 00:01:01,520 --> 00:01:04,410 in the correct position when the layout's display 20 00:01:04,410 --> 00:01:07,260 and that will remain below each other. 21 00:01:07,260 --> 00:01:09,360 So experiment with the font sizes and bold 22 00:01:09,360 --> 00:01:11,230 so that the text will look similar to what you can see 23 00:01:11,230 --> 00:01:13,370 in the screen with that image. 24 00:01:13,370 --> 00:01:14,460 All right, so that's the challenge. 25 00:01:14,460 --> 00:01:17,430 See how you go, pause the video and complete the challenge 26 00:01:17,430 --> 00:01:19,290 and I'll see you when you get back. 27 00:01:19,290 --> 00:01:20,303 Pause the video now. 28 00:01:26,670 --> 00:01:28,950 All right, so I'm going to start by ensuring 29 00:01:28,950 --> 00:01:31,037 that I've got the layout folder expanded, 30 00:01:31,037 --> 00:01:32,700 you can see here I've done that. 31 00:01:32,700 --> 00:01:35,820 And then I'm gonna right click on the layout folder, 32 00:01:35,820 --> 00:01:39,350 click on new and select layout resource file. 33 00:01:39,350 --> 00:01:40,810 And if you recall from the challenge, 34 00:01:40,810 --> 00:01:43,223 the file name we want is list_record. 35 00:01:46,560 --> 00:01:49,120 We root element, we're dealing with ConstraintLayout 36 00:01:49,120 --> 00:01:50,500 so it should be ConstraintLayout. 37 00:01:50,500 --> 00:01:53,520 I'm just gonna specify enough or top enough characters 38 00:01:53,520 --> 00:01:57,030 until that's specified in, double click it as you saw there. 39 00:01:57,030 --> 00:01:58,330 Everything else is fine on that point 40 00:01:58,330 --> 00:02:00,668 so I'm just gonna click on okay. 41 00:02:00,668 --> 00:02:02,717 And that's obviously showing on the screen there now. 42 00:02:02,717 --> 00:02:05,320 Now I'm just going to close down the project pane for now, 43 00:02:05,320 --> 00:02:07,070 taking there's a bit more space, 44 00:02:07,070 --> 00:02:10,130 and I'm gonna start by setting the default margin 45 00:02:10,130 --> 00:02:13,252 because most margins are gonna be 16 dp. 46 00:02:13,252 --> 00:02:15,750 So I'm gonna come up here to the default 47 00:02:15,750 --> 00:02:19,140 and specify 16 as the default margin. 48 00:02:19,140 --> 00:02:21,360 And I'm also gonna make sure autoconnect is off, 49 00:02:21,360 --> 00:02:24,870 you can see there that I've got the slash through it. 50 00:02:24,870 --> 00:02:26,690 So that autoconnect is off. 51 00:02:26,690 --> 00:02:30,523 Next, we're gonna drag three TextViews into the design. 52 00:02:31,650 --> 00:02:33,680 Now I'm gonna show one way to constraint the widgets 53 00:02:33,680 --> 00:02:37,060 to get the effect we want, but it's not the only way. 54 00:02:37,060 --> 00:02:39,080 For as long as your constraints keep the TextViews 55 00:02:39,080 --> 00:02:41,340 where they should be and allow them to grow 56 00:02:41,340 --> 00:02:43,680 without overlapping, then that's fine. 57 00:02:43,680 --> 00:02:46,430 All right, so let's go through and add three TextViews. 58 00:02:56,080 --> 00:02:57,537 All right, so we're going to start off now. 59 00:02:57,537 --> 00:03:00,070 I'm gonna go straight in the first view, 60 00:03:00,070 --> 00:03:03,000 or the first TextView to the top left and right 61 00:03:03,000 --> 00:03:04,133 inches of the layouts. 62 00:03:05,130 --> 00:03:06,280 I'm gonna go ahead and do that. 63 00:03:06,280 --> 00:03:10,823 So left first then top, and then right. 64 00:03:12,650 --> 00:03:15,080 Then we set to default margins to 16 which is correct, 65 00:03:15,080 --> 00:03:17,330 for left and right but for the top margin, 66 00:03:17,330 --> 00:03:19,260 I'm going to actually change that to eight, 67 00:03:19,260 --> 00:03:21,460 so it's a little bit closer towards the top. 68 00:03:22,480 --> 00:03:25,778 Then the ID for this one, instead of TextView, 69 00:03:25,778 --> 00:03:27,528 it's gonna be tvName. 70 00:03:29,357 --> 00:03:32,943 And we wanna set its width to match_constraint. 71 00:03:36,180 --> 00:03:37,900 And that's how we can fill the layout 72 00:03:37,900 --> 00:03:39,650 horizontally if necessary. 73 00:03:39,650 --> 00:03:43,335 Now the layout height, that's gonna be set to wrap_content 74 00:03:43,335 --> 00:03:44,970 so that the TextView can go down the screen 75 00:03:44,970 --> 00:03:47,700 to accommodate all the text it contains. 76 00:03:47,700 --> 00:03:50,057 And you can see there, that's already set to wrap_content 77 00:03:50,057 --> 00:03:51,530 so I don't need to make a change. 78 00:03:51,530 --> 00:03:54,320 Now, for the text size, you're not restricted 79 00:03:54,320 --> 00:03:56,570 to the values that appear in the dropdown by the way, 80 00:03:56,570 --> 00:03:59,590 so I come down here to text size and I click on that, 81 00:03:59,590 --> 00:04:00,970 you don't have to select one of those, 82 00:04:00,970 --> 00:04:02,690 instead, you can actually type it. 83 00:04:02,690 --> 00:04:05,650 So I'm gonna come up here and just type in 20sp 84 00:04:05,650 --> 00:04:07,650 which is a reasonable size of presenter. 85 00:04:08,620 --> 00:04:10,480 And finally when I come down here on the text style 86 00:04:10,480 --> 00:04:13,890 and click on B which is bold, you can see 87 00:04:13,890 --> 00:04:16,350 that's appeared bold now in the design. 88 00:04:16,350 --> 00:04:19,910 So basically, we got match_constraint, wrap_content, 89 00:04:19,910 --> 00:04:22,107 size of 20sp now. 90 00:04:24,080 --> 00:04:25,717 Just typing it again, I'm not sure what happened there. 91 00:04:25,717 --> 00:04:29,050 But 20sp, and you can see the text is now larger, 92 00:04:29,050 --> 00:04:31,050 so that's correct and we are still bold. 93 00:04:32,140 --> 00:04:34,380 All right, so moving down, the next widget, 94 00:04:34,380 --> 00:04:36,420 we click on that, next TextView, this one, 95 00:04:36,420 --> 00:04:39,203 we're going to have the ID of tvArtist. 96 00:04:42,010 --> 00:04:44,170 Now its top edge should be constraint 97 00:04:44,170 --> 00:04:47,430 to the bottom edge of tvName, so let's do that first. 98 00:04:47,430 --> 00:04:51,670 So top edge constrained to the bottom of tvName 99 00:04:51,670 --> 00:04:54,270 and also, the right edge should be constrained 100 00:04:54,270 --> 00:04:56,630 to the right edge of the layout. 101 00:04:56,630 --> 00:04:58,180 I'm gonna go ahead and do that. 102 00:05:00,300 --> 00:05:02,580 Now, I'm not gonna constraint the left edge to start with 103 00:05:02,580 --> 00:05:05,600 as it's something that you need to watch out for here 104 00:05:05,600 --> 00:05:08,290 because this TextView is constraint to the right edge 105 00:05:08,290 --> 00:05:11,490 of the layout and its width at the moment 106 00:05:11,490 --> 00:05:13,227 is set to wrap_content, the text, 107 00:05:13,227 --> 00:05:15,570 and it's gonna appear up against the right edge 108 00:05:15,570 --> 00:05:17,840 of the screen and the widget will expand 109 00:05:17,840 --> 00:05:19,620 to the left if it needs to. 110 00:05:19,620 --> 00:05:22,160 So that's fine, just be careful if we change 111 00:05:22,160 --> 00:05:23,370 the width to match_constraint now 112 00:05:25,030 --> 00:05:26,730 so it's similar, I'm gonna change in the width now, 113 00:05:26,730 --> 00:05:28,670 to match_constraint. 114 00:05:28,670 --> 00:05:31,010 Now, only use match_constraint for the layout width 115 00:05:31,010 --> 00:05:33,410 or layer height if it got a constraint set 116 00:05:33,410 --> 00:05:35,170 at both of the edges. 117 00:05:35,170 --> 00:05:36,750 Now for layout, and let's go with the set 118 00:05:36,750 --> 00:05:39,650 to match_constraint, which I've done here now, 119 00:05:39,650 --> 00:05:42,200 then you need to constraint the left and right edges. 120 00:05:42,200 --> 00:05:44,440 If layout height is set to match_constraint, 121 00:05:44,440 --> 00:05:47,420 then the top and bottom edge should be constrained. 122 00:05:47,420 --> 00:05:49,150 And if you think about it, match_constraint 123 00:05:49,150 --> 00:05:51,690 means that the size of the widget is constrained 124 00:05:51,690 --> 00:05:53,520 between the two boundaries. 125 00:05:53,520 --> 00:05:55,320 With one of the boundaries isn't the fall end, 126 00:05:55,320 --> 00:05:56,930 it's really hard for anything to work out 127 00:05:56,930 --> 00:05:58,830 what the result should be. 128 00:05:58,830 --> 00:06:00,580 But you'll often get away with that for the width, 129 00:06:00,580 --> 00:06:03,180 but you could do it for the height, you can get out results. 130 00:06:03,180 --> 00:06:05,780 Widgets overlapping others, widgets is a common symptom 131 00:06:05,780 --> 00:06:08,823 of using match_constraint when only one edge is constrained. 132 00:06:10,720 --> 00:06:13,340 Now, I'm just gonna change to widget to match_constraint, 133 00:06:13,340 --> 00:06:15,560 let's see how to use it properly here. 134 00:06:15,560 --> 00:06:18,490 Now, we need to constraint the left-hand edge 135 00:06:18,490 --> 00:06:21,190 to the left of the layout so that both edges 136 00:06:21,190 --> 00:06:22,510 are constrained. 137 00:06:22,510 --> 00:06:24,550 Now, we did have the TextView positioned 138 00:06:24,550 --> 00:06:27,610 at the right-hand side which kind of the effect we wanted. 139 00:06:27,610 --> 00:06:31,070 Note that the TextView fills the width of the screen. 140 00:06:31,070 --> 00:06:33,643 Let's just go ahead and do that, constraint it to the left. 141 00:06:36,220 --> 00:06:37,880 So I can see now that's the TextView 142 00:06:37,880 --> 00:06:39,467 fills the width of the screen. 143 00:06:39,467 --> 00:06:41,330 I'm gonna take a different approach though, 144 00:06:41,330 --> 00:06:44,550 I'll position the text to the right of the TextView. 145 00:06:44,550 --> 00:06:46,450 Now, there's actually a quick way to do that 146 00:06:46,450 --> 00:06:48,910 using the text alignment attribute. 147 00:06:48,910 --> 00:06:50,190 And we can come down here and see that, 148 00:06:50,190 --> 00:06:53,000 textAlignment, there's five options there. 149 00:06:53,000 --> 00:06:55,500 So the first two here, they actually align 150 00:06:55,500 --> 00:06:56,930 the text to the left. 151 00:06:56,930 --> 00:06:58,720 The difference though is that the first case 152 00:06:58,720 --> 00:07:00,750 for right to left languages. 153 00:07:00,750 --> 00:07:03,570 Now this middle button, that's set as the text 154 00:07:03,570 --> 00:07:06,810 in the TextView and the last two over here, 155 00:07:06,810 --> 00:07:09,130 they right align the text, again gathering 156 00:07:09,130 --> 00:07:10,850 for right to left languages. 157 00:07:10,850 --> 00:07:12,910 So if you choose the one with the vertical bar 158 00:07:12,910 --> 00:07:15,720 on the end here, that's what we're gonna be using, 159 00:07:15,720 --> 00:07:16,773 so we click on that. 160 00:07:18,027 --> 00:07:20,880 So I touched on that in an earlier section. 161 00:07:20,880 --> 00:07:23,320 There's two approaches to changing the alignment 162 00:07:23,320 --> 00:07:26,770 of something and we use an image in the earlier example. 163 00:07:26,770 --> 00:07:28,870 You can align the widget within the layout, 164 00:07:28,870 --> 00:07:31,350 which is what we did to TextView to start with, 165 00:07:31,350 --> 00:07:33,660 or you can align the widget's contents 166 00:07:33,660 --> 00:07:36,930 inside the widget which is what we're now doing. 167 00:07:36,930 --> 00:07:39,250 There's often no difference between the two approaches, 168 00:07:39,250 --> 00:07:42,610 they're just different ways to achieve the same effect. 169 00:07:42,610 --> 00:07:45,620 Now, before we constraint the third TextView, 170 00:07:45,620 --> 00:07:47,700 I wanna get this from the same right to the left 171 00:07:47,700 --> 00:07:50,190 largest tvName to make sure that that's specified, 172 00:07:50,190 --> 00:07:52,440 16, which is correct. 173 00:07:52,440 --> 00:07:54,440 But a top margin of zero. 174 00:07:54,440 --> 00:07:56,140 So I'm gonna go ahead and do that. 175 00:07:58,539 --> 00:08:00,227 Now the reason these TextViews have internal paddings 176 00:08:00,227 --> 00:08:02,610 and there's no need to have top margin here. 177 00:08:02,610 --> 00:08:04,537 For most rows, the name will be over to the left 178 00:08:04,537 --> 00:08:06,410 and the artist over to the right, 179 00:08:06,410 --> 00:08:08,880 so there's really no need in this particular case, 180 00:08:08,880 --> 00:08:10,380 the space them apart. 181 00:08:10,380 --> 00:08:15,380 And lastly, a text size of 18sp is probably sufficient here 182 00:08:15,790 --> 00:08:17,530 so we'll do that and the other thing we'll do 183 00:08:17,530 --> 00:08:20,673 is just making sure that it's set to bold. 184 00:08:21,720 --> 00:08:24,110 Okay, so that's tvArtist. 185 00:08:24,110 --> 00:08:26,000 Now the third one, third TextView, 186 00:08:26,000 --> 00:08:27,720 we're gonna call that tvSummary. 187 00:08:27,720 --> 00:08:31,063 I'm gonna click on that ID, tvSummary. 188 00:08:34,470 --> 00:08:36,409 Now, it's gonna have its top head constrained 189 00:08:36,409 --> 00:08:38,033 to the bottom edge of tvArtist. 190 00:08:38,929 --> 00:08:41,880 And its right and left edges constrained to the layout. 191 00:08:41,880 --> 00:08:42,880 So let's go ahead and do that. 192 00:08:42,880 --> 00:08:44,823 So I'll do the right left first. 193 00:08:48,736 --> 00:08:51,173 And as I mentioned, we're gonna set the top edge 194 00:08:51,173 --> 00:08:53,473 constraint to the bottom edge of tvArtist. 195 00:08:56,924 --> 00:09:00,613 We wanna make sure layout width is set to match_constraint. 196 00:09:02,553 --> 00:09:04,200 Now, the default font size of 40 197 00:09:04,200 --> 00:09:06,340 is probably okay for this one. 198 00:09:06,340 --> 00:09:08,840 I'm gonna set the top margin to eight. 199 00:09:08,840 --> 00:09:10,190 That's a little bit closer. 200 00:09:11,370 --> 00:09:13,347 All right, so I'll click over to the XML 201 00:09:13,347 --> 00:09:14,820 and just make sure that it's formatted. 202 00:09:14,820 --> 00:09:16,160 Over the last few times I've done that, 203 00:09:16,160 --> 00:09:17,813 I haven't needed to do anything. 204 00:09:19,520 --> 00:09:21,603 It's all nicely formatted, so that's good. 205 00:09:22,560 --> 00:09:24,660 Okay so now that we got a view to use to display 206 00:09:24,660 --> 00:09:27,140 the fields of our feed entry objects, 207 00:09:27,140 --> 00:09:29,910 it's time to create our own adaptor 208 00:09:29,910 --> 00:09:33,020 to extend the basic functionality of the array adaptor. 209 00:09:33,020 --> 00:09:35,070 Now if you remember from the discussion about how 210 00:09:35,070 --> 00:09:37,460 the ListView and adaptor worked together, 211 00:09:37,460 --> 00:09:39,300 the adaptor provides the ListView 212 00:09:39,300 --> 00:09:41,870 as a populated view to display. 213 00:09:41,870 --> 00:09:44,900 Now, the current and array adaptors, probably quite easy 214 00:09:44,900 --> 00:09:47,851 to understand because it uses a single TextView, 215 00:09:47,851 --> 00:09:51,910 as the view that it sends to the ListView to display, 216 00:09:51,910 --> 00:09:54,160 but here we've got three different TextViews, 217 00:09:54,160 --> 00:09:55,800 so how does that actually work? 218 00:09:55,800 --> 00:09:58,080 Let me just open the project pane, 219 00:09:58,080 --> 00:10:00,333 and have a list_item.xml. 220 00:10:02,200 --> 00:10:05,820 Now when we set up the TextView in the list_item.xml view, 221 00:10:05,820 --> 00:10:10,143 we created that just to contain literally a single TextView. 222 00:10:11,332 --> 00:10:13,140 You can see over there appTextView. 223 00:10:13,140 --> 00:10:14,920 So that was pretty straightforward. 224 00:10:14,920 --> 00:10:18,450 The array adaptor just uses this XML to create a Textview 225 00:10:18,450 --> 00:10:20,880 and then it puts the objects text into it 226 00:10:20,880 --> 00:10:23,460 before sending it to the ListView. 227 00:10:23,460 --> 00:10:26,810 But go back to our list_record.xml. 228 00:10:26,810 --> 00:10:29,003 Here, we've got these three TextViews, 229 00:10:29,840 --> 00:10:34,010 but they're all contained within the ConstraintLayout view. 230 00:10:34,010 --> 00:10:35,350 You can see over there the component tree. 231 00:10:35,350 --> 00:10:38,250 So ConstraintLayout and there's the three TextViews. 232 00:10:38,250 --> 00:10:40,060 Controls in that to the list that is (mumbles) 233 00:10:40,060 --> 00:10:41,727 is literally just a text too. 234 00:10:43,590 --> 00:10:46,100 So basically, ConstraintLayout to this particular case 235 00:10:46,100 --> 00:10:49,670 for list_record.xml, that's also a view. 236 00:10:49,670 --> 00:10:51,290 So technically, it's a view group, 237 00:10:51,290 --> 00:10:53,940 but a view group is really just another kind of view. 238 00:10:54,800 --> 00:10:57,090 Now the ListView which it is quite happy to be given 239 00:10:57,090 --> 00:10:59,650 a ConstraintLayout for the view it should use, 240 00:10:59,650 --> 00:11:01,520 and that it will display the ConstraintLayout 241 00:11:01,520 --> 00:11:04,193 including any other widgets that it contains. 242 00:11:05,280 --> 00:11:08,210 So keep in mind that when we talk about the adaptor, 243 00:11:08,210 --> 00:11:10,990 sending a view to the ListView, you can either set 244 00:11:10,990 --> 00:11:13,720 a single widget, such as the TextView 245 00:11:13,720 --> 00:11:17,950 that we're currently using, but it can also send back a view 246 00:11:17,950 --> 00:11:20,920 that contains other views, that's we're about to do 247 00:11:20,920 --> 00:11:23,030 for list_record.xml. 248 00:11:23,030 --> 00:11:26,320 So this view will happily display any view that it's given 249 00:11:26,320 --> 00:11:29,330 even if that view contains other views. 250 00:11:29,330 --> 00:11:31,750 So what we're gonna do with out custom adaptor, 251 00:11:31,750 --> 00:11:34,090 is change the text in each of the TextViews 252 00:11:34,090 --> 00:11:37,010 and send them all to the ListView, packaged inside 253 00:11:37,010 --> 00:11:38,910 the ConstraintLayout view. 254 00:11:38,910 --> 00:11:41,773 So we'll create our custom adaptor in the next video.