1 00:00:05,510 --> 00:00:05,860 Alright, 2 00:00:05,890 --> 00:00:11,220 so our recycler view's going to display a thumbnail of the photo with a title next to it. 3 00:00:11,300 --> 00:00:14,200 Now if you remember, when we used the list view in the top 10 4 00:00:14,230 --> 00:00:18,990 downloader app, we had to provide a basic layout to display the data in. 5 00:00:19,040 --> 00:00:25,520 Now that layout contained three text few widgets to show the app name, the artist and a summary. 6 00:00:25,530 --> 00:00:31,140 Now whenever the list view requested new data, we put the values into those three text views, and sent 7 00:00:31,140 --> 00:00:35,220 the entire view back to the list view to display. 8 00:00:35,220 --> 00:00:37,690 Now our recycler view works in a similar way. 9 00:00:37,950 --> 00:00:43,320 We need a basic layout that'll contain, in this case, an image view for the thumbnail, and a text view 10 00:00:43,380 --> 00:00:44,570 for the title. 11 00:00:44,580 --> 00:00:50,070 So what I'm going to do is create a new layout. So I'm going to right click on the res layout folder and select 12 00:00:50,070 --> 00:00:53,700 New, Layout resource file. 13 00:00:53,730 --> 00:00:56,090 Now this is for the initial browsing of the photos. 14 00:00:56,090 --> 00:01:00,550 So I'm going to call this one browse. 15 00:01:00,600 --> 00:01:03,370 I'm going to change the root element to be a linear layout, 16 00:01:03,420 --> 00:01:04,800 so I'm just going to type that, 17 00:01:05,400 --> 00:01:10,530 linear, so it selects, so it comes up with LinearLayout, double click that to select it. 18 00:01:10,790 --> 00:01:15,510 Now a LinearLayout's a very useful layout to use for something simple like this. 19 00:01:15,620 --> 00:01:19,830 So if we click OK at this point, leaving everything else as the default, we can have a look at how to use a 20 00:01:19,830 --> 00:01:23,800 linear layout, and how it is different to a constraint layout. 21 00:01:24,290 --> 00:01:29,300 Now firstly a linear layout doesn't give you much in the way of arranging the widgets it contains. 22 00:01:29,460 --> 00:01:32,220 It just really lets you place them alongside each other, 23 00:01:32,220 --> 00:01:37,380 if it's a horizontal linear layout, or one above the other when it's set to vertical. 24 00:01:37,380 --> 00:01:38,130 Now we want 25 00:01:38,240 --> 00:01:40,910 our image view and text view next to each other, 26 00:01:41,190 --> 00:01:47,400 so the first step is to select the layout, so we're going to select over here in the component tree. Then we're going to set the orientation, 27 00:01:47,400 --> 00:01:55,590 going back to our standard set of attributes, and it's making sure that that's now set to horizontal. Now 28 00:01:55,720 --> 00:02:00,660 I'm going to drag the two widgets onto it before I set any more attributes, so that we get a visual indication as things 29 00:02:00,660 --> 00:02:01,650 change. 30 00:02:01,650 --> 00:02:03,200 So first we need an image view, 31 00:02:03,510 --> 00:02:06,810 but before we can do that we need an image to display in it. 32 00:02:06,960 --> 00:02:09,919 Now when the app's running it'll be displaying our photos, 33 00:02:09,930 --> 00:02:15,310 but until then it needs a placeholder image to show, until it has the proper photo. 34 00:02:15,600 --> 00:02:20,700 So what I'm going to do is download an icon that'll serve as a placeholder image, and Google 35 00:02:20,700 --> 00:02:27,510 have a lot of really decent icons available at this address, so I'm going to bring that website up 36 00:02:28,080 --> 00:02:29,160 in a browser. 37 00:02:29,560 --> 00:02:31,050 We can download it from there. 38 00:02:31,420 --> 00:02:36,760 You can see the link there is design dot Google dot com slash icons. 39 00:02:36,790 --> 00:02:41,740 This is actually a great resource if you need icons, and the good thing is that Google have designed them all 40 00:02:41,920 --> 00:02:44,150 to work well with material design. 41 00:02:44,620 --> 00:02:54,010 So when scrolling down, about halfway down, we've got these major characters here, content, file, hardware. 42 00:02:54,320 --> 00:02:55,350 Come down here to image. 43 00:02:55,550 --> 00:02:57,070 This is the one that we actually want. 44 00:02:57,470 --> 00:03:02,300 And there's also within there, there's actually an icon that's also called image, in the image section, 45 00:03:04,070 --> 00:03:05,640 see over here, image. 46 00:03:05,660 --> 00:03:06,860 Now it's only an icon, 47 00:03:06,860 --> 00:03:08,250 not a full size image. 48 00:03:08,390 --> 00:03:10,920 So we're going to grab the largest size available. 49 00:03:11,090 --> 00:03:17,080 Now you choose the size by selecting an image. I'm going to click on image, then down the bottom, 50 00:03:17,090 --> 00:03:21,330 we come down here and we select the size we want, and what I'm going to do is select 48 51 00:03:21,360 --> 00:03:25,100 dp, the largest possible from the dropdown list. 52 00:03:25,100 --> 00:03:27,970 We want to download it as a png file. 53 00:03:28,450 --> 00:03:35,280 So what I'm going to do is come over here and click on the download button for pngs or ping files, and 54 00:03:35,280 --> 00:03:43,220 you can see that's brought that up on the screen there, and I'm going to just save that to my desk top. 55 00:03:43,550 --> 00:03:46,070 So it is basically a zip file that we've downloaded, 56 00:03:46,370 --> 00:03:51,740 and that's because it contains the icons and all the resolutions you need for an Android app, and even 57 00:03:51,740 --> 00:03:54,300 contains an IOS and web version as well. 58 00:03:54,530 --> 00:03:57,220 But at this point though I'm going to do something slightly strange. 59 00:03:57,300 --> 00:03:58,050 I'm going to go ahead 60 00:03:58,130 --> 00:03:58,940 and open the zip file. 61 00:04:00,110 --> 00:04:07,270 In my case I'm just going to navigate to the file to show it in finder, and I'm going to double click it on my Mac to unzip it, and you can see it's created 62 00:04:07,270 --> 00:04:10,050 this sub file so I'm going to double click it to get into that folder. 63 00:04:11,230 --> 00:04:15,760 And there's the three directories I was telling you about, and then double click into the Android 64 00:04:15,760 --> 00:04:21,700 folder. You can see that inside this, all these drawable directories at the various resolutions, and we can 65 00:04:21,700 --> 00:04:22,560 actually open them up, 66 00:04:28,510 --> 00:04:29,250 and you can see the files 67 00:04:29,250 --> 00:04:35,110 in each one of those. Now because we're using a small icon as an image, it's going to be scaled up when 68 00:04:35,110 --> 00:04:36,150 Android displays it 69 00:04:36,190 --> 00:04:41,980 in our app. Now normally we'd place each of these icon files in the appropriate MIP map directory 70 00:04:41,980 --> 00:04:47,760 in your project, so that the icons appear at the correct resolution on high density devices etcetera. 71 00:04:48,250 --> 00:04:52,000 But here though, we're using a small icon in place of an image, 72 00:04:52,000 --> 00:04:53,770 so it's going to be scaled up anyway. 73 00:04:54,130 --> 00:04:58,870 Now I wouldn't advocate doing this for most things, but in this case it's only a placeholder. 74 00:04:59,220 --> 00:05:04,300 And what's more it's only going to be visible when the image is loading, or if no matching photos are found, 75 00:05:04,300 --> 00:05:09,860 so what we're doing here should be fine, but bear in mind that this is not the way to handle icons 76 00:05:09,940 --> 00:05:12,250 that you're going to use in your app as icons. 77 00:05:12,430 --> 00:05:17,260 In that case what you want to do is copy each of the drawables that Google provides, into the resources 78 00:05:17,260 --> 00:05:23,320 directory of the same name, so that you get the correct resolution for each type of device. 79 00:05:23,320 --> 00:05:28,570 But what I'm going to do is extract the highest resolution icon, in this case it'll be from the drawable 80 00:05:28,840 --> 00:05:31,390 dash x x x hdpi, 81 00:05:31,720 --> 00:05:38,950 so that's the file there. I'm going to copy that, right click and select copy, and then I'm going to go back into 82 00:05:38,980 --> 00:05:40,010 Android Studio. 83 00:05:43,050 --> 00:05:45,870 I'm going to paste that into the drawable file, this one here, 84 00:05:47,450 --> 00:05:53,190 right click that and select paste. Now by the way Android Studio doesn't support copy and paste from a 85 00:05:53,190 --> 00:05:53,850 zip file, 86 00:05:54,150 --> 00:05:57,100 even if it does appear to be a folder in your systems file browser. 87 00:05:57,330 --> 00:06:02,190 So if you're doing that on Windows, you have to extract the file first and then copy the extracted file, and 88 00:06:02,500 --> 00:06:10,890 paste it into the drawable folder in Android Studio. And in this case what I'm going to do is just not use Android Studio's 89 00:06:11,010 --> 00:06:13,310 suggestion to create a drawable v 90 00:06:13,400 --> 00:06:19,320 24 folder. I'm just going to paste it into the root drawable file, I've made one there, and click on OK. 91 00:06:20,440 --> 00:06:21,420 And you can see our image now, 92 00:06:21,450 --> 00:06:25,660 ic underscore image underscore black 48dp is now in that drawable subfolder. 93 00:06:26,490 --> 00:06:31,390 And what I probably should have done before OKing that was actually rename it to placeholder dot 94 00:06:31,410 --> 00:06:34,240 png because it's a better name for what we're going to be using it for. 95 00:06:34,470 --> 00:06:38,000 But that's OK because I can do that now, right clicking it and do a Refactor, 96 00:06:38,190 --> 00:06:40,970 Rename, and again we'll call it placeholder, 97 00:06:43,840 --> 00:06:48,140 because it makes more sense to understand what this file is all about. 98 00:06:48,550 --> 00:06:48,940 Alright so 99 00:06:48,970 --> 00:06:53,140 now that we've done that, if we close down the project pane to give us a bit more space, 100 00:06:53,450 --> 00:06:58,670 and what I want to do is open up our new browse dot XML. You can see that's open up on the screen for us 101 00:06:58,680 --> 00:07:01,990 now. At the moment you can see it's got the linear layout over here. 102 00:07:02,290 --> 00:07:07,630 So what we'll do now is drag an image view on screen. Click on images over here or we can click on 103 00:07:07,630 --> 00:07:13,880 and drag an image view. So I'm just going to drag it in there for now. It doesn't really matter where you drag it, but once I do that 104 00:07:13,880 --> 00:07:19,130 you can see that Android Studio's asking for an image to display, and that's why we wanted to make sure that 105 00:07:19,130 --> 00:07:21,110 we had a placeholder image available. 106 00:07:21,280 --> 00:07:25,790 So I'm going to choose the placeholder images that we've downloaded and added to our project. 107 00:07:25,790 --> 00:07:26,660 I'm going to click on OK. 108 00:07:29,620 --> 00:07:34,180 So you can play at the scale type when the apps running, but for now I'm going to set that to fit start, 109 00:07:36,500 --> 00:07:41,000 and you can see that's still a little bit too big at the moment, so I'm going to set the layout width. I'm going to change that, 110 00:07:41,090 --> 00:07:43,430 instead of wrap content I'm going to change that to 80dp. 111 00:07:46,590 --> 00:07:51,120 And I'm also going to set the layout height to wrap content which it already is there. 112 00:07:51,700 --> 00:07:56,710 At the moment the icon, the image view rather, appears to fill the entire width of the layout as you can see, 113 00:07:56,840 --> 00:07:59,710 especially over here in the blue print view. 114 00:08:00,120 --> 00:08:03,740 So what we're going to do is drag a text view widget to the right of the image view, 115 00:08:04,260 --> 00:08:08,140 but don't worry about trying to make space for it because the layout's going to take care of that for us. 116 00:08:08,330 --> 00:08:15,580 So I'm going to come back to text, and I'm going to drag in a text view into the right and release, and you can see 117 00:08:15,580 --> 00:08:17,600 how space was automatically added for that, 118 00:08:17,620 --> 00:08:22,670 again that's got to do with the fact that we're using a linear layout. I'm just going to undo that again, 119 00:08:22,700 --> 00:08:27,410 and I just wanted to point out that when you do come over here, notice how we've got this green indication 120 00:08:27,890 --> 00:08:30,000 of where the text view's going to go. 121 00:08:30,240 --> 00:08:34,970 So in other words the green highlighting's showing which side it's going to go to. And that's all you can really 122 00:08:34,970 --> 00:08:40,010 do with a linear layout as far as positioning's concerned. You can put things next to each other, or above 123 00:08:40,010 --> 00:08:45,550 and below each other if the layout orientation's vertical, but of course our orientation's set to 124 00:08:45,550 --> 00:08:47,020 horizontal. 125 00:08:47,150 --> 00:08:50,750 That's basically it, so I'm going to drop it to the right of the image view, 126 00:08:51,170 --> 00:08:56,030 and you can see that the image view resizes to make room for it. Now we can space the widgets out, 127 00:08:56,250 --> 00:08:58,400 and there's a couple of ways to do that. 128 00:08:58,670 --> 00:09:03,260 First though, I think we should give these widgets ID's because we're going to need to refer to them 129 00:09:03,260 --> 00:09:11,990 in our code. So the image view, I'm going to click on that first, and we'll use the name thumbnail for that, 130 00:09:12,410 --> 00:09:12,920 thumbnail. 131 00:09:16,240 --> 00:09:24,240 Now the ID, the text for the ID rather, for the text view, we'll go with title for that. 132 00:09:24,360 --> 00:09:31,760 Now the most straightforward way to space these views out, is just to set margins. So we can actually expand the 133 00:09:31,760 --> 00:09:34,200 properties pane, 134 00:09:34,350 --> 00:09:42,590 and we can give text view a left margin. Let's expand so we can see some of these a little bit better, Layout 135 00:09:42,630 --> 00:09:51,100 underscore margin and click on left, select left, and we can give it a left margin of 16 dp, and you can see that 136 00:09:51,170 --> 00:09:56,860 a margin has now appeared in between our image view and our text view. And we want to remember to also set the start 137 00:09:57,340 --> 00:09:58,350 attribute as well, 138 00:09:58,480 --> 00:10:02,050 to the same, and we talked about the reasons for that in previous videos, 16 dp. 139 00:10:02,860 --> 00:10:08,280 And again as a refresher, we're targeting API 17 which introduced support for left to right languages 140 00:10:08,590 --> 00:10:10,570 which means you really only need a start attribute, 141 00:10:10,600 --> 00:10:12,000 but we're doing both anyway. 142 00:10:12,460 --> 00:10:18,220 Now if you want your app to run on devices before API 17, you should set the layout underscore margin 143 00:10:18,220 --> 00:10:21,890 start whenever you set layout underscore margin left. 144 00:10:22,200 --> 00:10:27,750 And similarly, always set layout underscore margin end to the same value as layout underscore margin 145 00:10:27,890 --> 00:10:32,080 right. Versions of Android that don't support right to left languages, 146 00:10:32,180 --> 00:10:38,050 will just use the left to right values. Later versions will use start end, and apply them to left or right 147 00:10:38,080 --> 00:10:40,600 as appropriate for the writing direction. 148 00:10:40,600 --> 00:10:45,080 Now I'm not going to set the left margin of the image view and right margin of the text view. 149 00:10:45,310 --> 00:10:46,330 Actually you can see though, 150 00:10:46,380 --> 00:10:49,930 they are too close to the edges, but also to the top as well. 151 00:10:50,170 --> 00:10:54,880 But to fix that problem we're going to be using padding inside the layout instead. 152 00:10:54,880 --> 00:10:59,740 So I want to come over here and select the layout, the linear layout in the component tree, and we want to come over here 153 00:10:59,740 --> 00:11:05,800 and expand padding under the extended attributes. Now you can set the padding on each one individually. 154 00:11:05,800 --> 00:11:13,980 bottom end left right start and top, but the first option all will set the padding for all sides at once. 155 00:11:14,140 --> 00:11:23,980 So I'm going to come over here and click into all, and make that 8 dp, and you can see when I've done that, it's all moved 156 00:11:23,980 --> 00:11:29,950 nicely, both the top left and right have all got now space around those widgets, which is exactly what we 157 00:11:29,950 --> 00:11:31,550 wanted to happen. 158 00:11:31,650 --> 00:11:34,040 Now margins and padding are very similar, 159 00:11:34,300 --> 00:11:41,530 but think of a margin as setting space around a widget, and padding setting space inside it. I'm going to 160 00:11:41,530 --> 00:11:42,600 be talking about this again 161 00:11:42,610 --> 00:11:48,250 when the app's running, because then we can experiment with some of the attributes and see their effects 162 00:11:48,250 --> 00:11:49,260 in the app. 163 00:11:49,390 --> 00:11:54,940 But notice that the two widgets have moved in and down, and that's because the padding inside the layout, forces 164 00:11:54,940 --> 00:11:56,620 them away from the edges. 165 00:11:56,620 --> 00:12:02,530 Now the text view's height and width both need to be set to wrap content, so lets select the title, the 166 00:12:03,250 --> 00:12:08,830 text view title there, and go back to our normal attributes, and you can see that they're both set currently correctly, 167 00:12:08,860 --> 00:12:09,920 to wrap content, 168 00:12:10,110 --> 00:12:13,730 and we're setting it to wrap content so that it can grow to cope with longer titles. 169 00:12:14,110 --> 00:12:20,350 So we've managed a bit of positioning by using margins and paddings, but it's a bit basic. We've also 170 00:12:20,350 --> 00:12:23,220 got our image view set to a fixed width. 171 00:12:23,330 --> 00:12:27,840 Now there is something else we can do, and that's to use what's known as weight. 172 00:12:27,950 --> 00:12:33,670 Now if you give the layout a weight, you can divide that number amongst the widgets so that they occupy 173 00:12:33,670 --> 00:12:35,880 a proportion of the available space. 174 00:12:36,220 --> 00:12:41,830 So as an example, let's make the image view occupy the left third of the screen, and the text view 175 00:12:41,830 --> 00:12:43,340 the remaining two thirds. 176 00:12:43,720 --> 00:12:47,630 So I'm going to start by selecting the layout, and we come over here, 177 00:12:47,650 --> 00:12:54,460 and go into our extended properties again, and we're looking for an attribute called weight sum. Now it should 178 00:12:54,460 --> 00:12:57,970 be right towards, or at the bottom. I'm going to scroll right down to the bottom there. 179 00:12:58,210 --> 00:13:00,510 There's weightSum, literally the last attribute. 180 00:13:00,520 --> 00:13:03,960 So what I'm going to do is enter a value of three there. 181 00:13:05,110 --> 00:13:11,020 And incidentally I noticed that there's some inconsistency between Android Studio Windows and Linux. So 182 00:13:11,320 --> 00:13:12,700 whenever you're setting an attribute, 183 00:13:12,700 --> 00:13:15,560 always check the section at the top first. 184 00:13:15,700 --> 00:13:21,290 This is the section I'm talking about, as right up here, otherwise you can waste time trying to find the 185 00:13:21,290 --> 00:13:22,340 attribute you want. 186 00:13:22,470 --> 00:13:26,660 On Linux it was at the bottom of the list, but on Android it was in the top section, and you can see here on 187 00:13:26,660 --> 00:13:34,410 a Mac weightSum was right down the bottom. Right so now that I've entered a value of weightSum for the layout, 188 00:13:34,610 --> 00:13:38,140 we can now use the layout underscore weight property for the image view. 189 00:13:38,150 --> 00:13:46,960 So I'm going to use the, select the image view, and the layout underscore weight, and there's layout underscore weight. You can 190 00:13:46,960 --> 00:13:49,900 see it's currently set to 1 which is the default, so 191 00:13:49,900 --> 00:13:54,480 I'm going to leave that on 1, but we're also going to change the text view's 192 00:13:54,660 --> 00:14:01,090 layout underscore weight to 2, and see that's currently set to 1, we're going to change that to 2. 193 00:14:01,550 --> 00:14:06,620 And then what we want to do now is change the layout underscore width for both widgets is to zero dp. 194 00:14:06,620 --> 00:14:09,550 So I'm going to go back to our normal attributes, and 195 00:14:09,690 --> 00:14:16,480 we've currently got the text selected, so I'm going to change the layout width to zero dp. 196 00:14:16,970 --> 00:14:26,190 We're going to do the same over here for the image view, the width to zero dp. You can see that once I've done 197 00:14:26,190 --> 00:14:32,460 that, they now fit nicely in their third or two thirds of the screen, and that'll happen even if I change 198 00:14:32,460 --> 00:14:39,230 the orientation to landscape. You can see they're still quite nicely using that appropriate area that we've 199 00:14:39,230 --> 00:14:42,460 defined. Now back to portrait. 200 00:14:42,540 --> 00:14:47,790 So now that we've got our calculated width for the image, we can change the image to views layout underscore 201 00:14:47,790 --> 00:14:50,120 height to match parent. 202 00:14:50,220 --> 00:14:52,820 So again I've got the image we selected, 203 00:14:53,160 --> 00:14:56,370 layout underscore height, we're going to change that to match parent. 204 00:14:58,240 --> 00:15:02,390 Right so let's finish this video here. In the next one we've got a few other things to talk about 205 00:15:02,500 --> 00:15:07,160 for this layout, and we're going to start by talking in the next video about adjusted view bounds. 206 00:15:07,260 --> 00:15:08,290 So see you in the next video.