1 00:00:00,000 --> 00:00:00,500 2 00:00:00,500 --> 00:00:03,990 TOMMY MACWILLIAM: In this video, we're going to write our first Android app. 3 00:00:03,990 --> 00:00:08,520 Our last video introduced us to a bunch of Java syntactic constructs. 4 00:00:08,520 --> 00:00:12,600 And now we're going to use those to create an Android app with some user 5 00:00:12,600 --> 00:00:14,550 interface elements. 6 00:00:14,550 --> 00:00:18,030 So there's a few more concepts to dive into before we 7 00:00:18,030 --> 00:00:21,420 start writing our first Android code. 8 00:00:21,420 --> 00:00:24,820 The first is the Android build system. 9 00:00:24,820 --> 00:00:28,020 So we've actually used this already in our last video 10 00:00:28,020 --> 00:00:30,400 just without really learning too much about it. 11 00:00:30,400 --> 00:00:34,170 The Android build system is called Gradle, which is actually 12 00:00:34,170 --> 00:00:38,820 an open source project you can use to build any type of Java application, 13 00:00:38,820 --> 00:00:42,300 but it takes care of a bunch of things like downloading libraries 14 00:00:42,300 --> 00:00:45,720 from third parties you might want to use and compiling things 15 00:00:45,720 --> 00:00:47,730 from Java into byte code. 16 00:00:47,730 --> 00:00:50,370 So we're going to be modifying some Gradle files as we 17 00:00:50,370 --> 00:00:53,940 make some of our Android applications. 18 00:00:53,940 --> 00:00:59,000 The next is another general software engineering concept called MVC. 19 00:00:59,000 --> 00:01:03,080 So MVC stands for Model View Controller. 20 00:01:03,080 --> 00:01:05,570 And it's a general design pattern that advocates 21 00:01:05,570 --> 00:01:09,410 separating out your logic, particularly of your app, 22 00:01:09,410 --> 00:01:12,150 into three different pieces. 23 00:01:12,150 --> 00:01:15,140 The first piece is called the model. 24 00:01:15,140 --> 00:01:20,090 And you can think about the model as the data that your app needs. 25 00:01:20,090 --> 00:01:23,400 So if you're displaying a list of items, for example, 26 00:01:23,400 --> 00:01:25,820 you might want to have a model that represents 27 00:01:25,820 --> 00:01:28,970 each item in the list or the list itself. 28 00:01:28,970 --> 00:01:32,300 In our last video, we created that track class. 29 00:01:32,300 --> 00:01:36,470 That's basically a model, because it's modeling some data 30 00:01:36,470 --> 00:01:40,330 that our application is going to use. 31 00:01:40,330 --> 00:01:44,890 On the other side of-- sort of the opposite of the model is the view. 32 00:01:44,890 --> 00:01:50,450 And you can think about the view as just how your data is going to be displayed. 33 00:01:50,450 --> 00:01:54,280 So the model doesn't say anything about how the data looks in your app 34 00:01:54,280 --> 00:01:55,180 or how it's used. 35 00:01:55,180 --> 00:02:00,070 It just says here's the data itself and here's how it's structured. 36 00:02:00,070 --> 00:02:04,720 On the other hand, the view says there's some data out there somewhere, 37 00:02:04,720 --> 00:02:07,480 I don't know what it is, but here's how we're 38 00:02:07,480 --> 00:02:12,560 going to display that data when we do have it. 39 00:02:12,560 --> 00:02:16,870 And lastly, the C, or controller, is sort of the bridge 40 00:02:16,870 --> 00:02:19,060 between the model and the view. 41 00:02:19,060 --> 00:02:21,250 So the controller might say, OK, I'm going 42 00:02:21,250 --> 00:02:25,420 to go grab some data from somewhere, get back some models, 43 00:02:25,420 --> 00:02:27,760 and send it to the view. 44 00:02:27,760 --> 00:02:30,920 And then the view might say, OK, someone just tapped on this button. 45 00:02:30,920 --> 00:02:34,480 The control will say, OK, great, let's respond to that button tap 46 00:02:34,480 --> 00:02:37,840 and maybe do something and update some model. 47 00:02:37,840 --> 00:02:41,020 So these three different components, we're going to work with all three 48 00:02:41,020 --> 00:02:44,680 of them when writing an Android app, where the model is going to be the data 49 00:02:44,680 --> 00:02:45,610 we're using. 50 00:02:45,610 --> 00:02:48,640 The view, a lot of this is going to be provided by Android. 51 00:02:48,640 --> 00:02:50,380 We don't need to write our own buttons. 52 00:02:50,380 --> 00:02:53,077 We can just use the buttons that Android provides. 53 00:02:53,077 --> 00:02:54,910 And then the controller is where we're going 54 00:02:54,910 --> 00:02:58,570 to put a lot of our application logic to sort of bridge those two 55 00:02:58,570 --> 00:02:59,920 things together. 56 00:02:59,920 --> 00:03:03,340 A few other concepts that are sort of Android specific. 57 00:03:03,340 --> 00:03:05,650 One is called activities. 58 00:03:05,650 --> 00:03:07,990 So we actually have already seen an activity. 59 00:03:07,990 --> 00:03:10,390 If you remember in that last app, we had something 60 00:03:10,390 --> 00:03:13,380 that extends AppCompat activity. 61 00:03:13,380 --> 00:03:18,250 And activity is sort of your base class for a screen in Android. 62 00:03:18,250 --> 00:03:20,380 So every time that you look at an Android screen, 63 00:03:20,380 --> 00:03:22,660 and maybe you're navigating from one to another, 64 00:03:22,660 --> 00:03:25,140 those are often different activities. 65 00:03:25,140 --> 00:03:28,690 And it's called an activity, because each screen basically represents 66 00:03:28,690 --> 00:03:31,660 one thing that you're trying to do. 67 00:03:31,660 --> 00:03:35,140 So for example, in your contacts app, the first activity 68 00:03:35,140 --> 00:03:38,260 might be a list of all of the contacts in your phone. 69 00:03:38,260 --> 00:03:40,720 And then when you select one, the second activity 70 00:03:40,720 --> 00:03:45,280 might be all of the information about just one single contact. 71 00:03:45,280 --> 00:03:49,140 So each of those would be represented with different classes 72 00:03:49,140 --> 00:03:52,180 and maybe their own models and views. 73 00:03:52,180 --> 00:03:54,600 Next is resources. 74 00:03:54,600 --> 00:03:59,290 And you can think of resources as all of the other stuff in your Android app 75 00:03:59,290 --> 00:04:01,910 that isn't just Java code. 76 00:04:01,910 --> 00:04:06,000 So one example of a type of resource is a layout. 77 00:04:06,000 --> 00:04:12,340 So a layout in an Android app is going to describe how a view should look. 78 00:04:12,340 --> 00:04:17,480 And layouts, under the hood, are defined using something called XML. 79 00:04:17,480 --> 00:04:20,600 And if you've used HTML before, they're really similar. 80 00:04:20,600 --> 00:04:24,610 XML is essentially just a more general version of that. 81 00:04:24,610 --> 00:04:31,850 But you'll have tags and you'll define a tag using that left and right bracket. 82 00:04:31,850 --> 00:04:35,700 So here, I've created a tag called linear layout. 83 00:04:35,700 --> 00:04:38,290 And my tag has one child. 84 00:04:38,290 --> 00:04:41,050 And that child is called a text view. 85 00:04:41,050 --> 00:04:45,430 And these are both happen to be things that Android defines for me. 86 00:04:45,430 --> 00:04:50,940 This linear layout tag says, inside of this is going to be some list of views, 87 00:04:50,940 --> 00:04:53,140 I'm going to lay them out either horizontally, 88 00:04:53,140 --> 00:04:57,760 one to the right of the other, or vertically, one on top of each other. 89 00:04:57,760 --> 00:05:02,690 Then this text to view is also an Android view that's defined for me. 90 00:05:02,690 --> 00:05:06,670 And it's this pretty simple view that just displays text. 91 00:05:06,670 --> 00:05:09,370 And so inside of this text view tag, I have 92 00:05:09,370 --> 00:05:12,020 something that's called an attribute. 93 00:05:12,020 --> 00:05:16,060 And so this attribute, its name, is android: text. 94 00:05:16,060 --> 00:05:18,440 And its value is hello. 95 00:05:18,440 --> 00:05:20,260 And this attribute name is special. 96 00:05:20,260 --> 00:05:22,390 It means something to Android. 97 00:05:22,390 --> 00:05:24,940 And in this case, it just happens to be the text that's 98 00:05:24,940 --> 00:05:28,220 going to be displayed in your app. 99 00:05:28,220 --> 00:05:30,790 Now you'll notice at the end of this text view tab 100 00:05:30,790 --> 00:05:33,755 I have this slash followed by the greater than. 101 00:05:33,755 --> 00:05:37,840 And that basically says this tag doesn't have anything inside of it. 102 00:05:37,840 --> 00:05:40,130 There's no children for this tag. 103 00:05:40,130 --> 00:05:43,420 That makes sense, because a text view is just sort of one view. 104 00:05:43,420 --> 00:05:46,450 Doesn't really make sense to put other views inside of this text view 105 00:05:46,450 --> 00:05:49,190 if we're just displaying simple string. 106 00:05:49,190 --> 00:05:52,930 And then lastly, we're closing this linear layout tag. 107 00:05:52,930 --> 00:05:55,600 So we're saying there's nothing else inside of our layout 108 00:05:55,600 --> 00:05:58,440 other than this one text view. 109 00:05:58,440 --> 00:06:01,080 And so as we're writing views for our Android app, 110 00:06:01,080 --> 00:06:03,900 we're going to be writing XML that looks like this, 111 00:06:03,900 --> 00:06:08,150 where you'll often have layouts, which sort of represent containers for views. 112 00:06:08,150 --> 00:06:10,870 And then you'll put views inside of those layouts. 113 00:06:10,870 --> 00:06:12,990 And Android will automatically lay them out 114 00:06:12,990 --> 00:06:15,540 on the screen in a way that makes sense. 115 00:06:15,540 --> 00:06:19,830 Another concept we'll see shortly is something called an intent. 116 00:06:19,830 --> 00:06:22,810 And an intent is a special object that's just 117 00:06:22,810 --> 00:06:25,800 defined somewhere in the Android SDK. 118 00:06:25,800 --> 00:06:30,660 And it represents a way to go from one activity to another. 119 00:06:30,660 --> 00:06:34,920 So an intent is going to specify things like, which activity should I 120 00:06:34,920 --> 00:06:39,180 open next, what's the class that corresponds to that activity, 121 00:06:39,180 --> 00:06:43,270 as well as any data you might want to pass in between activities. 122 00:06:43,270 --> 00:06:45,980 So if you have one activity where a user selects something 123 00:06:45,980 --> 00:06:50,070 and you want to take that selection and display it in a second activity, 124 00:06:50,070 --> 00:06:53,830 the intent is how you would pass that data back and forth. 125 00:06:53,830 --> 00:06:55,540 So we'll see that shortly. 126 00:06:55,540 --> 00:07:00,120 And finally, we're going to be writing something called a recycler view. 127 00:07:00,120 --> 00:07:05,040 And a recycler view is a really, really common class in a lot of Android apps. 128 00:07:05,040 --> 00:07:09,200 And it basically represents anything that's a list of items. 129 00:07:09,200 --> 00:07:12,960 So a lot of those infinitely scrolling lists, something like, 130 00:07:12,960 --> 00:07:17,040 Twitter is using a recycler view to show your list of tweets. 131 00:07:17,040 --> 00:07:19,230 Your phone application is using a recycler view 132 00:07:19,230 --> 00:07:21,750 to show a list of contacts in your phone. 133 00:07:21,750 --> 00:07:25,170 They're sort of the bread and butter of a lot of mobile applications. 134 00:07:25,170 --> 00:07:28,080 But all they do is really take some list of items 135 00:07:28,080 --> 00:07:30,310 and display them on your phone. 136 00:07:30,310 --> 00:07:34,320 What's nice about a recycler view is you might have a list of 1,000 things 137 00:07:34,320 --> 00:07:38,460 that you want to display, but there's no way that all 1,000 of those things 138 00:07:38,460 --> 00:07:41,160 are going to fit on your screen at once. 139 00:07:41,160 --> 00:07:44,040 So a recycler view has some nice optimizations 140 00:07:44,040 --> 00:07:48,660 built into it to dynamically put the right things in memory for your screen. 141 00:07:48,660 --> 00:07:52,200 So rather than loading everything into memory and all of those views 142 00:07:52,200 --> 00:07:55,740 into memory, which might be a lot and may be too much for your phone, 143 00:07:55,740 --> 00:07:59,270 it's only going to load in the things that are displayed on your screen, 144 00:07:59,270 --> 00:08:01,530 you know, plus or minus a few. 145 00:08:01,530 --> 00:08:04,660 And that's going to help keep your apps memory usage down, 146 00:08:04,660 --> 00:08:09,400 so it's not super slow and can run on all devices. 147 00:08:09,400 --> 00:08:13,230 So that's it for all the concepts we're going to use in our first Android app. 148 00:08:13,230 --> 00:08:15,220 So let's dive in. 149 00:08:15,220 --> 00:08:17,505 So I'm back in Android Studio. 150 00:08:17,505 --> 00:08:19,800 You'll notice that my emulator is still running. 151 00:08:19,800 --> 00:08:23,070 I like to leave it running because it can take some time to startup sometimes 152 00:08:23,070 --> 00:08:25,560 and there's no harm in leaving it running. 153 00:08:25,560 --> 00:08:29,670 So I'm going to come back over here and click Start a new Android Studio 154 00:08:29,670 --> 00:08:31,650 project. 155 00:08:31,650 --> 00:08:34,260 Just like before, I'm going to start with an empty activity, 156 00:08:34,260 --> 00:08:36,500 since I'm going to write everything myself. 157 00:08:36,500 --> 00:08:38,289 And now we know what activity means. 158 00:08:38,289 --> 00:08:41,100 It's just that one screen in our application. 159 00:08:41,100 --> 00:08:45,300 The application that we're going to be writing today is a pokedex. 160 00:08:45,300 --> 00:08:48,450 So we're going to take some list of pokemon, 161 00:08:48,450 --> 00:08:51,570 let the user browse through them, and when they select one, 162 00:08:51,570 --> 00:08:56,850 go to a second screen that displays some more information about that pokemon. 163 00:08:56,850 --> 00:09:00,390 So for our name, we're going to call it pokedex. 164 00:09:00,390 --> 00:09:05,160 Again, remember that this package name is just some, often domain name, 165 00:09:05,160 --> 00:09:06,032 backwards. 166 00:09:06,032 --> 00:09:07,740 Doesn't really matter what you pick here, 167 00:09:07,740 --> 00:09:11,970 so we're just going to say eduHarvardCS50Pokedex. 168 00:09:11,970 --> 00:09:13,380 We have where we want to save it. 169 00:09:13,380 --> 00:09:16,050 I'm just putting it on my desktop. 170 00:09:16,050 --> 00:09:18,060 We're going to use that same minimum API level 171 00:09:18,060 --> 00:09:20,160 as before, just targeting Android 5. 172 00:09:20,160 --> 00:09:21,990 It's up to you what you want to target. 173 00:09:21,990 --> 00:09:25,500 And then make sure we're using those AndroidX artifacts to use the latest 174 00:09:25,500 --> 00:09:29,218 version of the Android Support Library. 175 00:09:29,218 --> 00:09:30,510 So we're going to click finish. 176 00:09:30,510 --> 00:09:34,530 And just like before, Android Studio is going to automatically generate 177 00:09:34,530 --> 00:09:36,030 some files for me. 178 00:09:36,030 --> 00:09:38,250 But this time let's actually walk through what 179 00:09:38,250 --> 00:09:41,250 Android Studio has generated. 180 00:09:41,250 --> 00:09:44,370 So I'm going to come over here on the left 181 00:09:44,370 --> 00:09:48,865 and I'm going to start with this file called AndroidManifest.xml. 182 00:09:48,865 --> 00:09:52,700 I'm going to double click that to open it up. 183 00:09:52,700 --> 00:09:55,110 And this is the first xml file that we've seen. 184 00:09:55,110 --> 00:09:58,440 So we've just looked at what that xml syntax means. 185 00:09:58,440 --> 00:10:02,100 So we can see here that we have some root element. 186 00:10:02,100 --> 00:10:03,810 Element is called manifest. 187 00:10:03,810 --> 00:10:07,320 And this is just specifying to Android what our package name was, 188 00:10:07,320 --> 00:10:09,530 just to make sure we can launch it. 189 00:10:09,530 --> 00:10:13,330 And then we have one tag here called application. 190 00:10:13,330 --> 00:10:17,370 And you can see here that there's a few different attributes defined. 191 00:10:17,370 --> 00:10:19,940 We have things like our icon that we're going 192 00:10:19,940 --> 00:10:26,260 to use for the app, what the name of our app is, the theme of our app. 193 00:10:26,260 --> 00:10:31,320 And then next we have are the activities that are used in the app. 194 00:10:31,320 --> 00:10:33,750 So these were automatically generated for us. 195 00:10:33,750 --> 00:10:38,190 We have one activity here that's called main activity. 196 00:10:38,190 --> 00:10:41,370 And then here, we're just declaring a few different things 197 00:10:41,370 --> 00:10:43,203 that this activity is allowed to do. 198 00:10:43,203 --> 00:10:45,870 You don't have to worry too much about what these are right now. 199 00:10:45,870 --> 00:10:47,970 We'll be adding another one of these later. 200 00:10:47,970 --> 00:10:51,150 But this basically is a configuration file 201 00:10:51,150 --> 00:10:53,970 that Android can use in order to launch the app. 202 00:10:53,970 --> 00:10:57,600 So from this configuration file, Android can figure out 203 00:10:57,600 --> 00:11:00,390 all of the different activities your app is using. 204 00:11:00,390 --> 00:11:03,880 And it needs that sort of information for the system to work correctly 205 00:11:03,880 --> 00:11:07,230 and for everything to sort of launch the way you expect. 206 00:11:07,230 --> 00:11:10,770 So we won't modify this file too much. 207 00:11:10,770 --> 00:11:12,037 Let's see what else we've got. 208 00:11:12,037 --> 00:11:13,620 We've already seen this main activity. 209 00:11:13,620 --> 00:11:16,170 That's the same as it was last time. 210 00:11:16,170 --> 00:11:20,310 In this package we have a couple different test files. 211 00:11:20,310 --> 00:11:23,670 So we might want to write some tests for our Android application 212 00:11:23,670 --> 00:11:27,660 to make sure that, let's say, when you're doing some manipulation of data, 213 00:11:27,660 --> 00:11:30,160 that the result of what you expect it to be. 214 00:11:30,160 --> 00:11:32,950 So you can automatically write some tests here. 215 00:11:32,950 --> 00:11:37,090 And there's just a couple different packages for you to do that. 216 00:11:37,090 --> 00:11:40,440 So we won't be looking at those right now. 217 00:11:40,440 --> 00:11:42,750 Next, we have this res folder. 218 00:11:42,750 --> 00:11:44,910 And that's short for resource. 219 00:11:44,910 --> 00:11:50,230 So the ones that we are going to look at are first, our layout. 220 00:11:50,230 --> 00:11:53,690 So recall that the layout is where we define 221 00:11:53,690 --> 00:11:57,170 what views are going to be in each activity 222 00:11:57,170 --> 00:12:00,600 and how those views are laid out relative to each other. 223 00:12:00,600 --> 00:12:02,960 So Android has this kind of nice drag and drop editor, 224 00:12:02,960 --> 00:12:05,660 if you just want to sort of drag around buttons onto your screen 225 00:12:05,660 --> 00:12:07,740 and see what the screen would look like. 226 00:12:07,740 --> 00:12:11,900 But if you come down to the bottom here, we have this tab that says text. 227 00:12:11,900 --> 00:12:17,410 If you click that, then you can see the underlying XML for these views. 228 00:12:17,410 --> 00:12:20,270 In these videos, we're mostly going to be working in XML, 229 00:12:20,270 --> 00:12:22,280 but you're also welcome to use the design view 230 00:12:22,280 --> 00:12:24,680 and drag and drop just to start prototyping your apps 231 00:12:24,680 --> 00:12:26,805 and sort of see what it looks like. 232 00:12:26,805 --> 00:12:29,180 So let's just quickly walk through what's happening here. 233 00:12:29,180 --> 00:12:31,490 This is a pretty simple layout. 234 00:12:31,490 --> 00:12:35,360 It looks like we have this tag here, called ConstraintLayout. 235 00:12:35,360 --> 00:12:37,670 Here's that AndroidX package we used before. 236 00:12:37,670 --> 00:12:41,030 Again, this is just sort of a set of classes and libraries 237 00:12:41,030 --> 00:12:43,520 that your Android app might want to use. 238 00:12:43,520 --> 00:12:47,960 So this ConstraintLayout is just a way of laying out 239 00:12:47,960 --> 00:12:49,190 views inside of each other. 240 00:12:49,190 --> 00:12:52,820 And you can sort of attach constraints, as we'll see here. 241 00:12:52,820 --> 00:12:55,550 So don't to worry as much about these two attributes. 242 00:12:55,550 --> 00:12:57,590 They're just sort of setup for Android saying 243 00:12:57,590 --> 00:13:02,030 we're using this sort of Android dialect of XML. 244 00:13:02,030 --> 00:13:04,480 Next are two attributes we'll see a lot. 245 00:13:04,480 --> 00:13:07,580 And this is the layout_width and the layout_height. 246 00:13:07,580 --> 00:13:14,280 And so this defines, as you'd guess, the width and the height of this view. 247 00:13:14,280 --> 00:13:18,470 So you'll see that they're both set to a value of match_parent. 248 00:13:18,470 --> 00:13:23,090 And so this means that I want the width and height of this view 249 00:13:23,090 --> 00:13:26,360 to be the same as whatever my parent is. 250 00:13:26,360 --> 00:13:31,040 So basically, fill all of the space that my parent has. 251 00:13:31,040 --> 00:13:36,050 And because this is the first thing in our app, there's no parent really, 252 00:13:36,050 --> 00:13:38,660 we're going to fill the entire screen. 253 00:13:38,660 --> 00:13:41,660 So this makes sense to sort of be the root of our application, 254 00:13:41,660 --> 00:13:45,500 because we want our activity to use the entire screen of the phone. 255 00:13:45,500 --> 00:13:48,170 So by saying match_parent on both of these, we're just saying, 256 00:13:48,170 --> 00:13:50,878 OK, we've got this root element, it's the same size of the phone, 257 00:13:50,878 --> 00:13:55,110 we can put other views wherever we want. 258 00:13:55,110 --> 00:13:57,500 And again, then this context just specifies 259 00:13:57,500 --> 00:14:04,710 that this activity, this XML file, applies to a class called MainActivity. 260 00:14:04,710 --> 00:14:08,330 And that's the name of the class that was automatically generated. 261 00:14:08,330 --> 00:14:09,380 OK, so that's the layout. 262 00:14:09,380 --> 00:14:11,047 That's not actually displaying anything. 263 00:14:11,047 --> 00:14:15,620 That's just saying here's how everything inside of me is going to be laid out. 264 00:14:15,620 --> 00:14:17,810 And now we have a text view. 265 00:14:17,810 --> 00:14:20,420 Remember that that text view is just a simple way 266 00:14:20,420 --> 00:14:23,637 to display text on the screen. 267 00:14:23,637 --> 00:14:26,720 So you'll notice here, the layout width and height are a little different. 268 00:14:26,720 --> 00:14:32,380 Rather than saying match_parent, we specified a value of wrap_content. 269 00:14:32,380 --> 00:14:35,780 And so that basically means, I want the width and height 270 00:14:35,780 --> 00:14:39,440 to be dynamic based on my contents. 271 00:14:39,440 --> 00:14:43,160 So there's a string here, we can see it's just hello world. 272 00:14:43,160 --> 00:14:46,280 And this is saying that the size of the text view 273 00:14:46,280 --> 00:14:50,840 is just big enough to contain the string hello world. 274 00:14:50,840 --> 00:14:54,290 Lastly, we have these layout constraints. 275 00:14:54,290 --> 00:15:00,080 And we can use these constraints because we're inside of a ConstraintLayout. 276 00:15:00,080 --> 00:15:04,340 So you can see that we're constraining the bottom of this text view 277 00:15:04,340 --> 00:15:07,452 to the bottom of its parent, the left to the left of its parent. 278 00:15:07,452 --> 00:15:08,660 It's kind of straightforward. 279 00:15:08,660 --> 00:15:12,590 But it's basically saying, pin all of the top, bottom, left, 280 00:15:12,590 --> 00:15:17,450 and right of this view to be the exact same as my parent. 281 00:15:17,450 --> 00:15:19,520 And so the result of this is that we're basically 282 00:15:19,520 --> 00:15:23,150 centering this text view on the screen, which you may 283 00:15:23,150 --> 00:15:25,400 remember when we ran the app last time. 284 00:15:25,400 --> 00:15:27,410 We're saying we just wanted to display the text 285 00:15:27,410 --> 00:15:31,640 and show just enough space for the entire string hello world to be there. 286 00:15:31,640 --> 00:15:33,890 But then there's all that space around it, 287 00:15:33,890 --> 00:15:37,700 just make it exactly centered inside of my ConstraintLayout. 288 00:15:37,700 --> 00:15:39,950 And that ConstraintLayout is the entire screen, 289 00:15:39,950 --> 00:15:42,860 so this just centers something on the screen. 290 00:15:42,860 --> 00:15:44,150 Pretty simple. 291 00:15:44,150 --> 00:15:49,340 You'll also notice on the resources over here, we have a couple other XML files. 292 00:15:49,340 --> 00:15:54,740 Just to take a look at one of them, we have this file called strings.xml. 293 00:15:54,740 --> 00:15:58,070 And this is kind of nice where you can put a bunch of your string constants 294 00:15:58,070 --> 00:16:00,517 that you might want to display in the UI. 295 00:16:00,517 --> 00:16:02,600 Later down the line, if you're writing an app that 296 00:16:02,600 --> 00:16:04,827 supports multiple languages, for example, 297 00:16:04,827 --> 00:16:07,160 this can come in handy, because you can just say, here's 298 00:16:07,160 --> 00:16:10,670 a list of all my elements in English, here's a list of everything in Spanish, 299 00:16:10,670 --> 00:16:12,500 and just sort of swap them out. 300 00:16:12,500 --> 00:16:17,240 But if you come back to that Android manifest file we looked at before, 301 00:16:17,240 --> 00:16:20,080 we're actually using some of these. 302 00:16:20,080 --> 00:16:25,310 So you can see here that this label attribute is saying @string. 303 00:16:25,310 --> 00:16:29,490 And that's saying give me something out of that strings.xml file. 304 00:16:29,490 --> 00:16:34,140 Then it's saying /app_name, which represents something with this name. 305 00:16:34,140 --> 00:16:37,820 So all this manifest file is doing is basically referencing 306 00:16:37,820 --> 00:16:40,430 something else in this other XML file. 307 00:16:40,430 --> 00:16:43,070 And so you'll see that as you're browsing through some code, 308 00:16:43,070 --> 00:16:47,910 things like, this one is referencing something in the style.xml file. 309 00:16:47,910 --> 00:16:51,000 So something in there has a name of AppTheme. 310 00:16:51,000 --> 00:16:55,862 If we open that up, sure enough, there is our name of AppTheme. 311 00:16:55,862 --> 00:16:57,570 So you can read the Android documentation 312 00:16:57,570 --> 00:17:01,560 to see a bit more what different colors and themes and other things you 313 00:17:01,560 --> 00:17:03,430 can use these resources for. 314 00:17:03,430 --> 00:17:05,730 But at the end of the day, they're all just XML sort 315 00:17:05,730 --> 00:17:10,560 of following that same format, and Android just tells you what type of XML 316 00:17:10,560 --> 00:17:15,380 to write and how to configure things to do what you want. 317 00:17:15,380 --> 00:17:19,310 The last thing that we can take a look at is our Gradle scripts. 318 00:17:19,310 --> 00:17:23,780 So remember that Gradle is the build system for Android. 319 00:17:23,780 --> 00:17:28,160 So when you're writing C code, you could specify a bunch of different flags 320 00:17:28,160 --> 00:17:29,610 to the C compiler. 321 00:17:29,610 --> 00:17:33,900 Gradle is basically a wrapper around the Java compiler. 322 00:17:33,900 --> 00:17:39,240 And you can use it to specify flags and dependencies and things like that. 323 00:17:39,240 --> 00:17:44,720 So if I open up this second Gradle file here, this one that says module app, 324 00:17:44,720 --> 00:17:47,120 this is what a Gradle file looks like. 325 00:17:47,120 --> 00:17:51,100 It's actually written in this other programming language called Groovy, 326 00:17:51,100 --> 00:17:55,080 but you can just think about it as a configuration file. 327 00:17:55,080 --> 00:17:56,930 So here, you can see a bunch of the stuff 328 00:17:56,930 --> 00:18:01,280 that we specified when we were creating that Android project. 329 00:18:01,280 --> 00:18:04,730 So you can remember that we set our minimum SDK version, 330 00:18:04,730 --> 00:18:06,650 our target SDK version. 331 00:18:06,650 --> 00:18:09,080 We created that package name. 332 00:18:09,080 --> 00:18:13,310 And all Android Studio did was generate this Gradle file based 333 00:18:13,310 --> 00:18:16,070 on what you typed into that wizard. 334 00:18:16,070 --> 00:18:20,360 And the section that we care about is this dependencies section. 335 00:18:20,360 --> 00:18:24,260 And this is where you're going to be adding libraries, either from Android 336 00:18:24,260 --> 00:18:26,450 itself or from third-party developers. 337 00:18:26,450 --> 00:18:29,030 We're going to see an example of both. 338 00:18:29,030 --> 00:18:32,540 But here, you can see we're already using a few libraries. 339 00:18:32,540 --> 00:18:36,200 We saw that we had that AndroidX AppCompat class. 340 00:18:36,200 --> 00:18:39,530 That was the base class that our activity extended. 341 00:18:39,530 --> 00:18:41,340 So here's where that came from. 342 00:18:41,340 --> 00:18:45,740 We actually downloaded in the background some library from AndroidX. 343 00:18:45,740 --> 00:18:48,770 Its version was 1.1.0. 344 00:18:48,770 --> 00:18:50,150 And then we could use that. 345 00:18:50,150 --> 00:18:54,920 Similarly, that ConstraintLayout, that also came from a library. 346 00:18:54,920 --> 00:18:58,370 It came from this library called androidx.constraintlayout, 347 00:18:58,370 --> 00:18:59,900 happens to have a version. 348 00:18:59,900 --> 00:19:03,650 And Gradle took care of downloading those libraries, putting them somewhere 349 00:19:03,650 --> 00:19:08,240 our application could use, and then all we have to do is import them. 350 00:19:08,240 --> 00:19:09,410 And that's basically it. 351 00:19:09,410 --> 00:19:11,390 There's a few other files that were generated, 352 00:19:11,390 --> 00:19:13,142 but we're not too worried about those. 353 00:19:13,142 --> 00:19:15,350 But that's everything that we're going to need to use 354 00:19:15,350 --> 00:19:18,000 to write our Android application. 355 00:19:18,000 --> 00:19:21,110 So now, let's jump back to our main activity 356 00:19:21,110 --> 00:19:24,380 and get started writing our Android app. 357 00:19:24,380 --> 00:19:29,130 So I'm just going to close out these other files that we looked at. 358 00:19:29,130 --> 00:19:32,360 So we're going to be using a recycler view. 359 00:19:32,360 --> 00:19:36,440 And that recycler view is going to be used to display a long list of pokemon 360 00:19:36,440 --> 00:19:40,220 on the screen and handle everything from scrolling and making sure 361 00:19:40,220 --> 00:19:43,050 that everything fits on the screen. 362 00:19:43,050 --> 00:19:49,970 So the first thing I want to do is add the RecyclerView to my application. 363 00:19:49,970 --> 00:19:53,060 So if I come over to developer.android.com, 364 00:19:53,060 --> 00:19:56,030 you're going to find a ton of resources for Android. 365 00:19:56,030 --> 00:19:58,370 The documentation is actually really, really good. 366 00:19:58,370 --> 00:19:59,100 It's really nice. 367 00:19:59,100 --> 00:20:01,350 There are lots of different tutorials and walkthroughs 368 00:20:01,350 --> 00:20:03,600 that'll sort of give you examples of a bunch of things 369 00:20:03,600 --> 00:20:05,940 you might want to do in your app. 370 00:20:05,940 --> 00:20:10,460 And so here's what the documentation for RecyclerView looks like. 371 00:20:10,460 --> 00:20:12,762 So notice, it even starts with the glossary of terms. 372 00:20:12,762 --> 00:20:14,720 We're going to go through all of this together. 373 00:20:14,720 --> 00:20:18,710 But then at the end, it will list out all of the different methods and fields 374 00:20:18,710 --> 00:20:20,968 that RecyclerView has. 375 00:20:20,968 --> 00:20:22,760 So if you're wondering how to do something, 376 00:20:22,760 --> 00:20:26,450 the Android documentation is a great first stop. 377 00:20:26,450 --> 00:20:29,690 OK, so let's jump back to our application. 378 00:20:29,690 --> 00:20:34,620 And the first thing we want to do is add the RecyclerView library to our app. 379 00:20:34,620 --> 00:20:37,640 So to do that, we're going to open that Gradle file. 380 00:20:37,640 --> 00:20:41,690 And then we're going to line add a line that looks just like this. 381 00:20:41,690 --> 00:20:44,510 So rather than saying androidx.constraintlayout, 382 00:20:44,510 --> 00:20:48,140 we're going to say androidx.recyclerview. 383 00:20:48,140 --> 00:20:49,670 That's sort of the package name. 384 00:20:49,670 --> 00:20:52,970 Then the name of that library is RecyclerView. 385 00:20:52,970 --> 00:20:56,480 And I happen to know that the most recent version is 1.1.0. 386 00:20:56,480 --> 00:21:00,260 You can find that just by browsing the Android documentation. 387 00:21:00,260 --> 00:21:03,140 So now I get this message in Android Studio that's the Gradle files 388 00:21:03,140 --> 00:21:03,860 have changed. 389 00:21:03,860 --> 00:21:04,490 Yes, they have. 390 00:21:04,490 --> 00:21:05,720 I just changed them. 391 00:21:05,720 --> 00:21:09,350 And so if I click this sync button, what this is going to do 392 00:21:09,350 --> 00:21:12,620 is build the project, download any of the libraries 393 00:21:12,620 --> 00:21:15,590 that I just specified from the internet, and put them in a place 394 00:21:15,590 --> 00:21:16,850 where I can use them. 395 00:21:16,850 --> 00:21:18,890 So it looks like my build succeeded, which 396 00:21:18,890 --> 00:21:23,010 means we just downloaded RecyclerView, and now we can use it. 397 00:21:23,010 --> 00:21:25,700 So when writing an Android app, I like to start 398 00:21:25,700 --> 00:21:30,440 with the view to sort of understand what it is I want my app to be doing. 399 00:21:30,440 --> 00:21:32,750 Then from the view, think about what models 400 00:21:32,750 --> 00:21:35,390 I'll need to create to [INAUDIBLE] power that view. 401 00:21:35,390 --> 00:21:39,570 And then lastly, write the controller to hook up those two things. 402 00:21:39,570 --> 00:21:40,680 So let's do just that. 403 00:21:40,680 --> 00:21:43,860 Let's start by looking at the view. 404 00:21:43,860 --> 00:21:46,190 So let's open up our main activity. 405 00:21:46,190 --> 00:21:48,620 And we know that we don't really need a text view anymore, 406 00:21:48,620 --> 00:21:52,440 because we want to replace that with a recycler view. 407 00:21:52,440 --> 00:21:55,090 So let's start typing RecyclerView. 408 00:21:55,090 --> 00:21:57,590 And again, autocomplete is really going to help me out here. 409 00:21:57,590 --> 00:22:01,370 I just hit enter, and, boom, I have the full path to that recycler view. 410 00:22:01,370 --> 00:22:03,350 I didn't have to memorize that. 411 00:22:03,350 --> 00:22:06,080 And then it even added in these width and height attributes, 412 00:22:06,080 --> 00:22:07,370 since they're required. 413 00:22:07,370 --> 00:22:10,460 You need to specify the size of any view that you add. 414 00:22:10,460 --> 00:22:13,653 And then it also told me what values I can put there. 415 00:22:13,653 --> 00:22:15,320 So we've already looked at both of them. 416 00:22:15,320 --> 00:22:18,020 There's wrap_content and match_parent. 417 00:22:18,020 --> 00:22:22,680 And in this case, we want the recycler view to fill the entire screen. 418 00:22:22,680 --> 00:22:25,400 So I'm just going to say match_parent here. 419 00:22:25,400 --> 00:22:27,470 I just hit enter and Android Studio jumped me 420 00:22:27,470 --> 00:22:29,700 to the next thing, which is really nice. 421 00:22:29,700 --> 00:22:31,040 So that's match_parent. 422 00:22:31,040 --> 00:22:33,290 I'm going to say match_parent there. 423 00:22:33,290 --> 00:22:36,200 And then if I just type a slash, Android's 424 00:22:36,200 --> 00:22:39,080 going to close that tag for me. 425 00:22:39,080 --> 00:22:41,120 So now, I can get rid of this. 426 00:22:41,120 --> 00:22:44,690 427 00:22:44,690 --> 00:22:50,360 And I just have a single recycler view filling up the entire screen. 428 00:22:50,360 --> 00:22:53,520 Before we finish here we want to do one more thing, 429 00:22:53,520 --> 00:22:57,320 and that's to add an ID to that recycler view. 430 00:22:57,320 --> 00:22:59,960 So inside of our controller, we're eventually 431 00:22:59,960 --> 00:23:02,510 going to want to manipulate that recycler view. 432 00:23:02,510 --> 00:23:07,760 And in order to do that, we need a way to reference this view. 433 00:23:07,760 --> 00:23:09,770 And the way that Android enables you to do that 434 00:23:09,770 --> 00:23:14,960 is by giving each view a unique identifier that you specify. 435 00:23:14,960 --> 00:23:19,730 And then you can use that identifier from your Java code and your controller 436 00:23:19,730 --> 00:23:23,880 to access the object that represents this view. 437 00:23:23,880 --> 00:23:26,510 So giving something ID's is really easy. 438 00:23:26,510 --> 00:23:31,670 I can just say Android: id, autocomplete is going to help me out. 439 00:23:31,670 --> 00:23:36,680 And now every ID starts with this prefix here that, again, autocomplete told me, 440 00:23:36,680 --> 00:23:39,140 which is @+id/. 441 00:23:39,140 --> 00:23:40,700 Great, I'll hit enter. 442 00:23:40,700 --> 00:23:43,220 And now I can type in the name of my ID. 443 00:23:43,220 --> 00:23:45,980 I'm only going to have recycler view, so we're just 444 00:23:45,980 --> 00:23:49,450 going to call this RecyclerView. 445 00:23:49,450 --> 00:23:50,150 And there we go. 446 00:23:50,150 --> 00:23:54,910 So now I have a way for my Java code to reference this recycler 447 00:23:54,910 --> 00:23:57,530 view, which we're going to need. 448 00:23:57,530 --> 00:24:01,750 So that's the list, but we also need a way 449 00:24:01,750 --> 00:24:07,340 to define what each row in our recycler view looks like. 450 00:24:07,340 --> 00:24:10,750 So to do that, we're going to create a second layout. 451 00:24:10,750 --> 00:24:16,760 And this layout is going to represent just the row in the recycler view. 452 00:24:16,760 --> 00:24:18,730 So let's come over to the left hand side. 453 00:24:18,730 --> 00:24:23,260 We're going to control click on layout, because we want to create a file there. 454 00:24:23,260 --> 00:24:29,140 Then we're going to come over here to new, and then layout resource file. 455 00:24:29,140 --> 00:24:30,100 Looks good. 456 00:24:30,100 --> 00:24:32,780 So now it's just asking me for a file name. 457 00:24:32,780 --> 00:24:36,150 Let's call this pokedex_row. 458 00:24:36,150 --> 00:24:40,510 And then it's also asking me what we want the root element to be. 459 00:24:40,510 --> 00:24:43,150 Before we used that ConstraintLayout, which 460 00:24:43,150 --> 00:24:45,970 allows you to constrain things to the screen. 461 00:24:45,970 --> 00:24:50,090 Here let's just use a linear layout, which is a little bit simpler. 462 00:24:50,090 --> 00:24:52,570 It's just going to layout views right next to each other. 463 00:24:52,570 --> 00:24:54,320 And a row is just going to have one view, 464 00:24:54,320 --> 00:24:57,010 so let's just use that, because it's simple. 465 00:24:57,010 --> 00:25:01,383 Nothing else here really matters, so let's just click OK. 466 00:25:01,383 --> 00:25:02,050 And there we go. 467 00:25:02,050 --> 00:25:07,200 So now we've generated a second XML file that we can use. 468 00:25:07,200 --> 00:25:12,150 We're going to get rid of Gradle for now, come down here to text, 469 00:25:12,150 --> 00:25:15,490 and get the XML that was generated And you can see here, 470 00:25:15,490 --> 00:25:17,320 it's pretty much the same. 471 00:25:17,320 --> 00:25:18,600 We have a linear layout. 472 00:25:18,600 --> 00:25:22,530 The width and height are going to match the parent, whatever my parent is, just 473 00:25:22,530 --> 00:25:24,060 fill it. 474 00:25:24,060 --> 00:25:29,380 And now inside of this layout, we now want to create a text view. 475 00:25:29,380 --> 00:25:33,030 So again, we have to specify the width and the height of this text view. 476 00:25:33,030 --> 00:25:35,160 So we're just going to say I want it to be 477 00:25:35,160 --> 00:25:38,290 the same as my parent for both of them. 478 00:25:38,290 --> 00:25:42,180 And then we also want to give this text view an ID. 479 00:25:42,180 --> 00:25:45,540 So let's say my ID. 480 00:25:45,540 --> 00:25:49,774 Let's just call this pokedex_row_text_view. 481 00:25:49,774 --> 00:25:52,900 482 00:25:52,900 --> 00:25:54,010 Close it out. 483 00:25:54,010 --> 00:25:57,160 And while we're here, let's also give this root element an ID, 484 00:25:57,160 --> 00:25:59,060 because we might need that later. 485 00:25:59,060 --> 00:26:05,983 So we'll say android: id, and this is just my pokedex_row. 486 00:26:05,983 --> 00:26:08,650 And again, we want to make sure we're not closing this tag here, 487 00:26:08,650 --> 00:26:11,033 because there's something inside of it. 488 00:26:11,033 --> 00:26:12,450 So this is a pretty simple layout. 489 00:26:12,450 --> 00:26:13,950 It's even simpler than the last one. 490 00:26:13,950 --> 00:26:17,040 We just have a linear layout and one thing inside of that, 491 00:26:17,040 --> 00:26:19,080 and that's going to be a text view. 492 00:26:19,080 --> 00:26:21,550 And then later, we're going to be using that. 493 00:26:21,550 --> 00:26:26,980 So now that my layout is finished, I'm pretty much done with the view. 494 00:26:26,980 --> 00:26:30,240 So now let's think about the model. 495 00:26:30,240 --> 00:26:33,100 Our pokedex is going to be pretty simple to start. 496 00:26:33,100 --> 00:26:35,680 The only data that we're going to have is the name 497 00:26:35,680 --> 00:26:38,020 of the pokemon and it's number. 498 00:26:38,020 --> 00:26:40,630 So every Pokemon has a unique number that can you 499 00:26:40,630 --> 00:26:43,240 can express using an integer. 500 00:26:43,240 --> 00:26:48,700 So let's now create a Java class to represent a single pokemon. 501 00:26:48,700 --> 00:26:51,430 So I'm going to come back over here to the left hand side, 502 00:26:51,430 --> 00:26:57,840 going to control click here, and I'm going to create a new Java class. 503 00:26:57,840 --> 00:26:59,290 It's name is going to be Pokemon. 504 00:26:59,290 --> 00:27:06,060 No superclass, no interface, just a regular class, nothing else to do here. 505 00:27:06,060 --> 00:27:09,410 And much like before, we have this empty class. 506 00:27:09,410 --> 00:27:12,320 So let's give it a couple of properties. 507 00:27:12,320 --> 00:27:17,880 Let's say we have a property called name and a property called number. 508 00:27:17,880 --> 00:27:19,880 We're going to keep these private, because we're 509 00:27:19,880 --> 00:27:21,920 going to write getters later. 510 00:27:21,920 --> 00:27:25,800 Now let's create a constructor. 511 00:27:25,800 --> 00:27:29,802 The constructor is going to take a name and a number. 512 00:27:29,802 --> 00:27:31,260 All we're going to do is save them. 513 00:27:31,260 --> 00:27:37,340 514 00:27:37,340 --> 00:27:41,270 And now let's write two getters, just to keep these things private, 515 00:27:41,270 --> 00:27:44,090 in case we want to change how they're implemented later. 516 00:27:44,090 --> 00:27:47,510 So we're going to say public String getName(). 517 00:27:47,510 --> 00:27:48,890 That's just going to return name. 518 00:27:48,890 --> 00:27:52,230 519 00:27:52,230 --> 00:27:56,070 And then we're going to say public int getnumber(). 520 00:27:56,070 --> 00:27:59,213 And that's just going to return number. 521 00:27:59,213 --> 00:28:01,380 And you'll notice that Android Studio is nice enough 522 00:28:01,380 --> 00:28:03,330 to even suggest the names of the getters, 523 00:28:03,330 --> 00:28:07,008 just to really minimize how much code I'm writing. 524 00:28:07,008 --> 00:28:07,800 And so there we go. 525 00:28:07,800 --> 00:28:10,680 And so you'll notice we didn't write setters here either, 526 00:28:10,680 --> 00:28:14,340 because this class is basically a read-only class. 527 00:28:14,340 --> 00:28:18,630 You might find this called a value class somewhere in Java as well. 528 00:28:18,630 --> 00:28:20,380 But there's no sort of other methods. 529 00:28:20,380 --> 00:28:22,590 It's just a container for these two data types, 530 00:28:22,590 --> 00:28:27,640 so that you can have one object encapsulate both a name and a number. 531 00:28:27,640 --> 00:28:29,210 OK, so that's it for our model. 532 00:28:29,210 --> 00:28:30,830 Pretty simple. 533 00:28:30,830 --> 00:28:36,450 And so now the last thing we want to do is hook up a recycler view. 534 00:28:36,450 --> 00:28:42,170 So a recycler view has another class attached to it called an adapter. 535 00:28:42,170 --> 00:28:45,180 And the adapter class basically defines what 536 00:28:45,180 --> 00:28:48,810 data is going to be displayed in the recycler view 537 00:28:48,810 --> 00:28:52,410 and then how that data should appear on the screen. 538 00:28:52,410 --> 00:28:56,260 So I know that I want to create a new class. 539 00:28:56,260 --> 00:29:00,390 So I'm going to come over here to the left, say new Java class, 540 00:29:00,390 --> 00:29:04,260 and we're going to call this PokedexAdapter. 541 00:29:04,260 --> 00:29:08,950 Again, no superclass or interface, so same as what we're used to. 542 00:29:08,950 --> 00:29:11,910 So this is the class that's going to represent all 543 00:29:11,910 --> 00:29:15,960 of the data inside of my recycler view. 544 00:29:15,960 --> 00:29:19,290 The base class for this class is going to be something 545 00:29:19,290 --> 00:29:22,180 that's given to us by RecyclerView. 546 00:29:22,180 --> 00:29:27,600 So I'm going to say extends RecyclerView, nicely automatically 547 00:29:27,600 --> 00:29:31,240 imported it for me, dot adapter. 548 00:29:31,240 --> 00:29:34,620 And so this is a class that's given to me from RecyclerView, 549 00:29:34,620 --> 00:29:36,900 so it has a bunch of methods inside of it. 550 00:29:36,900 --> 00:29:40,980 And it also has a few methods that it requires me to implement myself. 551 00:29:40,980 --> 00:29:43,140 And this class is also a generic class. 552 00:29:43,140 --> 00:29:48,510 And it takes, as its sort of type, something called a view holder. 553 00:29:48,510 --> 00:29:53,910 Now a view holder is what's going to, as it sounds like, hold a view. 554 00:29:53,910 --> 00:29:57,330 And it's going to allow me to manipulate what's on the screen. 555 00:29:57,330 --> 00:30:00,550 So we're going to say, here's a view that's displayed on the screen. 556 00:30:00,550 --> 00:30:03,810 I'm going to define a little object to hold onto that view. 557 00:30:03,810 --> 00:30:08,887 And from there I can modify some of those layout elements I just described. 558 00:30:08,887 --> 00:30:10,720 So we're going to write this class, as well. 559 00:30:10,720 --> 00:30:13,530 We haven't created it yet, but we're going 560 00:30:13,530 --> 00:30:16,110 to call it PokedexAdapter.PokedexViewHolder. 561 00:30:16,110 --> 00:30:19,950 562 00:30:19,950 --> 00:30:22,860 So let's go ahead and define that right now. 563 00:30:22,860 --> 00:30:26,700 We're going to make this private, because nothing outside of the adapter 564 00:30:26,700 --> 00:30:30,550 is actually going to use this class, so no need to make it public. 565 00:30:30,550 --> 00:30:31,800 So we're going to say private. 566 00:30:31,800 --> 00:30:34,050 We'll make it a static class here, so we can 567 00:30:34,050 --> 00:30:37,890 say PokedexAdapter.PokedexViewHolder. 568 00:30:37,890 --> 00:30:43,240 And now we're going to call it PokdexViewHolder. 569 00:30:43,240 --> 00:30:47,145 And now we're just going to extend it a RecyclerView.ViewHolder. 570 00:30:47,145 --> 00:30:49,690 571 00:30:49,690 --> 00:30:54,520 And so now we've defined this valid class that we can use and pass in. 572 00:30:54,520 --> 00:30:56,740 So let's add a constructor to this class. 573 00:30:56,740 --> 00:31:01,540 Let's say-- forgot the word class. 574 00:31:01,540 --> 00:31:03,540 That's why the compiler is not happy with me. 575 00:31:03,540 --> 00:31:06,990 So now let's say PokedexViewHolder. 576 00:31:06,990 --> 00:31:10,890 And it's going to take as its parameter one thing. 577 00:31:10,890 --> 00:31:12,950 And that's a view. 578 00:31:12,950 --> 00:31:14,880 And you'll see here that this is basically 579 00:31:14,880 --> 00:31:18,010 the most generic view possible. 580 00:31:18,010 --> 00:31:22,620 Basically, all of the Android views are going to subclass from this base view. 581 00:31:22,620 --> 00:31:26,680 So it's just sort of the most generic thing. 582 00:31:26,680 --> 00:31:32,280 And so now this ViewHolder, we now want to create fields for those two things 583 00:31:32,280 --> 00:31:34,100 we added IDs to. 584 00:31:34,100 --> 00:31:38,100 If we jump back to that Pokedex view, the view we want to hold 585 00:31:38,100 --> 00:31:39,480 is one of these. 586 00:31:39,480 --> 00:31:40,680 And it has two things. 587 00:31:40,680 --> 00:31:42,420 It has a layout we care about. 588 00:31:42,420 --> 00:31:45,220 And it has a text view that we care about. 589 00:31:45,220 --> 00:31:49,050 So let's go ahead and add fields to this view holder class 590 00:31:49,050 --> 00:31:51,640 to represent those two things. 591 00:31:51,640 --> 00:31:56,030 So we're going to have a linear layout. 592 00:31:56,030 --> 00:31:59,730 And let's call that our containerView. 593 00:31:59,730 --> 00:32:03,110 And it's also going to have a text view. 594 00:32:03,110 --> 00:32:06,670 And let's just call that our textView. 595 00:32:06,670 --> 00:32:12,850 So now we want to access those views from this base view. 596 00:32:12,850 --> 00:32:15,750 And remember, the reason we gave those things IDs 597 00:32:15,750 --> 00:32:17,670 was so that we could do just this. 598 00:32:17,670 --> 00:32:22,380 We can go from our Java code, grab the object representing a text 599 00:32:22,380 --> 00:32:25,620 view or linear layout, and get it back. 600 00:32:25,620 --> 00:32:30,840 So the way to do that is to say containerView = view. 601 00:32:30,840 --> 00:32:32,550 That's the view that was passed in. 602 00:32:32,550 --> 00:32:36,300 Then there's this method findViewById. 603 00:32:36,300 --> 00:32:38,858 And you'll notice that it looks like it takes an integer, 604 00:32:38,858 --> 00:32:39,900 but that's kind of weird. 605 00:32:39,900 --> 00:32:42,300 We gave things strings. 606 00:32:42,300 --> 00:32:44,520 Something that's happening under the hood 607 00:32:44,520 --> 00:32:49,800 is that Android Studio and Gradle are automatically generating unique IDs 608 00:32:49,800 --> 00:32:51,690 for all of those strings. 609 00:32:51,690 --> 00:32:54,800 And they put them inside of this class called R. 610 00:32:54,800 --> 00:32:56,550 And the R stands for resource. 611 00:32:56,550 --> 00:32:58,590 And it has a bunch of methods that you can use 612 00:32:58,590 --> 00:33:01,500 to access these different resources. 613 00:33:01,500 --> 00:33:04,450 The resource we care about is id. 614 00:33:04,450 --> 00:33:10,080 And if I say R.id, you can notice that here are the IDs that I created. 615 00:33:10,080 --> 00:33:12,870 Autocomplete is really going to help you here, in case you forget. 616 00:33:12,870 --> 00:33:19,230 So if I just say R.id.pokedex_row, this represents a unique ID. 617 00:33:19,230 --> 00:33:25,740 It's an integer that Android generated for me that represents this container. 618 00:33:25,740 --> 00:33:29,250 So I can get the text view in the exact same way. 619 00:33:29,250 --> 00:33:34,980 I can say textView = view.findViewById(R.id.pokedex row text 620 00:33:34,980 --> 00:33:35,790 view). 621 00:33:35,790 --> 00:33:41,700 622 00:33:41,700 --> 00:33:44,800 And it's automatically also going to give me back the right type, 623 00:33:44,800 --> 00:33:48,200 so I don't have to worry about any of that. 624 00:33:48,200 --> 00:33:51,220 OK, so that's it for our view holder for now. 625 00:33:51,220 --> 00:33:53,590 All we've done is we've taken this view that's 626 00:33:53,590 --> 00:33:55,520 passed in from the recycler view. 627 00:33:55,520 --> 00:33:59,120 And we've converted into something that we can actually use. 628 00:33:59,120 --> 00:34:04,240 So now, the last thing to do is to implement a few methods that 629 00:34:04,240 --> 00:34:07,780 are defined on recycler view adapter. 630 00:34:07,780 --> 00:34:12,250 The first method that we're going to override from our recycler view adapter 631 00:34:12,250 --> 00:34:14,860 is called onCreateViewHolder. 632 00:34:14,860 --> 00:34:17,920 I can just start typing onCreate and autocomplete is 633 00:34:17,920 --> 00:34:19,480 going to do the work for me. 634 00:34:19,480 --> 00:34:25,420 So this is a method that's called when I want to create a new view holder, which 635 00:34:25,420 --> 00:34:27,199 makes sense. 636 00:34:27,199 --> 00:34:32,530 So the first thing we want to do is get our layout file. 637 00:34:32,530 --> 00:34:36,530 So we want to go from a layout to a view. 638 00:34:36,530 --> 00:34:41,400 And so the way to do that is we're going to create a new variable, called View. 639 00:34:41,400 --> 00:34:47,110 And this is going to use this Android class, called LayoutInflator. 640 00:34:47,110 --> 00:34:49,160 Let autocomplete take care of that. 641 00:34:49,160 --> 00:34:53,780 And then we're going to call a method on LayoutInflator called from. 642 00:34:53,780 --> 00:34:57,820 And this is basically saying, where do I want to get my layout from. 643 00:34:57,820 --> 00:35:00,932 There's this argument that's passed in, called parent. 644 00:35:00,932 --> 00:35:02,140 We're just going to use that. 645 00:35:02,140 --> 00:35:05,290 Don't worry too much about what that one means. 646 00:35:05,290 --> 00:35:09,820 What actually matters is this thing called inflate. 647 00:35:09,820 --> 00:35:17,750 So inflate is going to say I want to go from some XML file to a Java view. 648 00:35:17,750 --> 00:35:22,810 And so we need to pass in what file we want to inflate. 649 00:35:22,810 --> 00:35:28,540 So we want to inflate our R.layout.pokdex_row. 650 00:35:28,540 --> 00:35:33,440 And again, just like we had that R.id generated for us, 651 00:35:33,440 --> 00:35:36,550 we also have this R.layout generated for us, 652 00:35:36,550 --> 00:35:38,770 which again, has a bunch of these unique IDs 653 00:35:38,770 --> 00:35:42,230 that we can use in a lot of these methods. 654 00:35:42,230 --> 00:35:47,060 Now from the documentation, this method also takes a couple of the parameters. 655 00:35:47,060 --> 00:35:48,820 One is a parent. 656 00:35:48,820 --> 00:35:50,950 That's passed in for me. 657 00:35:50,950 --> 00:35:53,530 And then last, we can just pass in false. 658 00:35:53,530 --> 00:35:56,320 This is just some different behaviors you might want to do. 659 00:35:56,320 --> 00:36:00,490 We're not really worried about that, so we can just say false. 660 00:36:00,490 --> 00:36:04,630 And so now what we've done is we've converted this XML 661 00:36:04,630 --> 00:36:07,270 file into a Java object in memory. 662 00:36:07,270 --> 00:36:10,420 So this is our view that we want to hold. 663 00:36:10,420 --> 00:36:15,160 And you'll notice that the return type of this method is a PokdexViewHolder. 664 00:36:15,160 --> 00:36:19,870 So let's just return a new PokedexViewHolder. 665 00:36:19,870 --> 00:36:22,930 And we're going to give it that view to hold. 666 00:36:22,930 --> 00:36:25,960 That's the first method that we need to implement. 667 00:36:25,960 --> 00:36:31,150 The second method we want to implement is called onBindViewHolder. 668 00:36:31,150 --> 00:36:35,320 Now this is the method that's going to be called whenever a view scrolls 669 00:36:35,320 --> 00:36:38,740 into screen and we say, we need to set the value 670 00:36:38,740 --> 00:36:42,050 or set the values inside of this row. 671 00:36:42,050 --> 00:36:46,300 So here is where we're going to want to actually set the different properties 672 00:36:46,300 --> 00:36:49,120 of the view that we've created. 673 00:36:49,120 --> 00:36:53,570 But you'll notice that we don't yet have any data. 674 00:36:53,570 --> 00:36:55,100 So let's do that. 675 00:36:55,100 --> 00:36:58,540 Let's just hard code a few Pokemon to start. 676 00:36:58,540 --> 00:37:02,380 So to do that I'm going to create a new list. 677 00:37:02,380 --> 00:37:08,220 The type of this list is going to be our pokemon class. 678 00:37:08,220 --> 00:37:10,740 And we'll just call it pokemon. 679 00:37:10,740 --> 00:37:12,600 Android Studio trying to be helpful here, 680 00:37:12,600 --> 00:37:16,410 but it's not as well versed in the pokemon universe as we are. 681 00:37:16,410 --> 00:37:20,700 And just as we did before, we're going to use that nice Arrays.asList 682 00:37:20,700 --> 00:37:23,970 utility to create some pokemon. 683 00:37:23,970 --> 00:37:26,700 So now, inside of this list, let's just create a few. 684 00:37:26,700 --> 00:37:30,510 So there's first Pokemon. 685 00:37:30,510 --> 00:37:32,880 Its name is Bulbasaur. 686 00:37:32,880 --> 00:37:36,900 Its number is 1. 687 00:37:36,900 --> 00:37:39,940 Next-- whoops. 688 00:37:39,940 --> 00:37:43,480 Next one, the name is Ivysaur, number is 2. 689 00:37:43,480 --> 00:37:46,462 690 00:37:46,462 --> 00:37:48,940 Make sure that's a comma, not a semicolon. 691 00:37:48,940 --> 00:37:54,450 And lastly, we have name of Venusaur. 692 00:37:54,450 --> 00:37:55,310 His number is 3. 693 00:37:55,310 --> 00:37:57,820 694 00:37:57,820 --> 00:38:00,130 So that's a really simple model for now. 695 00:38:00,130 --> 00:38:01,210 It's just hard coded. 696 00:38:01,210 --> 00:38:03,880 We're later going to dynamically generate this list, 697 00:38:03,880 --> 00:38:06,860 but let's just start by hard coding it. 698 00:38:06,860 --> 00:38:14,310 So now in onBindViewHolder, we want to go from this model to our view. 699 00:38:14,310 --> 00:38:17,150 And remember, that's quintessentially what a controller is doing, 700 00:38:17,150 --> 00:38:20,040 is going from a model to a view. 701 00:38:20,040 --> 00:38:22,820 So let's grab an element out of this array. 702 00:38:22,820 --> 00:38:29,400 So let's say our current pokemon is using this list. 703 00:38:29,400 --> 00:38:31,050 And which one do we want to get? 704 00:38:31,050 --> 00:38:35,280 Well, it looks like this method has this other parameter called position. 705 00:38:35,280 --> 00:38:38,850 And that's going to represent what row we're currently in. 706 00:38:38,850 --> 00:38:43,770 So we just want to get the pokemon at that position. 707 00:38:43,770 --> 00:38:50,440 So now, we want to just go ahead and set the values for this row. 708 00:38:50,440 --> 00:38:54,690 So first, we notice that when we came up to here to the view holder, 709 00:38:54,690 --> 00:38:56,580 we made these two things private. 710 00:38:56,580 --> 00:38:59,490 Again, that's sort of convention, but just for speed, let's just 711 00:38:59,490 --> 00:39:02,020 make these public for now. 712 00:39:02,020 --> 00:39:05,890 And while I'm here, I also notice we forgot to call super on this, 713 00:39:05,890 --> 00:39:07,620 so let's make sure we do that. 714 00:39:07,620 --> 00:39:10,153 Again, you want to make sure that you're calling super, just 715 00:39:10,153 --> 00:39:12,570 in case those super classes are doing something important. 716 00:39:12,570 --> 00:39:16,240 In this case, it probably is, so let's go ahead and do that. 717 00:39:16,240 --> 00:39:21,610 So the only thing we need to do to this row right now is to set its text. 718 00:39:21,610 --> 00:39:23,170 So let's go ahead and do that. 719 00:39:23,170 --> 00:39:25,590 So we have an instance of a view holder. 720 00:39:25,590 --> 00:39:27,855 We just made textView public. 721 00:39:27,855 --> 00:39:31,380 And so now we can call this method setText. 722 00:39:31,380 --> 00:39:34,530 You'll notice that there is a version that takes a string. 723 00:39:34,530 --> 00:39:38,690 So we can just say current.getName. 724 00:39:38,690 --> 00:39:42,570 And this is saying I want to take that name object, set 725 00:39:42,570 --> 00:39:45,137 that to be the text of the row. 726 00:39:45,137 --> 00:39:45,720 And that's it. 727 00:39:45,720 --> 00:39:46,902 This is void method. 728 00:39:46,902 --> 00:39:49,110 We don't have to do anything else, because we've just 729 00:39:49,110 --> 00:39:52,130 modified this view holder. 730 00:39:52,130 --> 00:39:55,700 Now the last method we have to define on our adapter 731 00:39:55,700 --> 00:39:58,460 is how many rows to display. 732 00:39:58,460 --> 00:40:03,690 So if I start typing item, there's this method called itemCount. 733 00:40:03,690 --> 00:40:06,658 And now we need to return the size of our list. 734 00:40:06,658 --> 00:40:08,450 Well, we know what the size of our list is. 735 00:40:08,450 --> 00:40:10,200 It's just however big this array is. 736 00:40:10,200 --> 00:40:12,740 So we can just return pokemon.size. 737 00:40:12,740 --> 00:40:16,117 738 00:40:16,117 --> 00:40:16,700 And that's it. 739 00:40:16,700 --> 00:40:21,560 Now we have a fully working recycler view adapter. 740 00:40:21,560 --> 00:40:27,120 So the last thing to do is to actually use this adapter. 741 00:40:27,120 --> 00:40:30,980 So to do that, I'm going to come back to my main activity, 742 00:40:30,980 --> 00:40:35,350 and I'm going to add a few more fields that a recycler view needs. 743 00:40:35,350 --> 00:40:37,180 So we're back in main activity. 744 00:40:37,180 --> 00:40:38,970 So let's add a few fields. 745 00:40:38,970 --> 00:40:42,930 The first is our recycler view. 746 00:40:42,930 --> 00:40:45,390 We'll just call that RecyclerView. 747 00:40:45,390 --> 00:40:47,380 Now we need a couple other things. 748 00:40:47,380 --> 00:40:49,920 One is our adapter. 749 00:40:49,920 --> 00:40:55,250 So we know that we've called that our pokedex view adapter, 750 00:40:55,250 --> 00:40:57,620 but we'll just use the generic version here. 751 00:40:57,620 --> 00:40:59,062 We'll call that adapter. 752 00:40:59,062 --> 00:41:01,520 And lastly, we just need something called a layout manager. 753 00:41:01,520 --> 00:41:04,420 754 00:41:04,420 --> 00:41:07,080 And we'll just call that layout manager. 755 00:41:07,080 --> 00:41:09,330 So those are the three fields that we're going to need 756 00:41:09,330 --> 00:41:12,360 to instantiate our recycler view. 757 00:41:12,360 --> 00:41:15,030 And so now let's instantiate them. 758 00:41:15,030 --> 00:41:21,490 So our recycler view is going to be this findViewById thing again. 759 00:41:21,490 --> 00:41:24,630 So remember, now we're in our main activity layout file. 760 00:41:24,630 --> 00:41:29,550 In there, recall that we created an ID called RecyclerView. 761 00:41:29,550 --> 00:41:32,190 So really easy way to get that. 762 00:41:32,190 --> 00:41:35,160 And so now we need to set those adapters. 763 00:41:35,160 --> 00:41:41,370 So we can say my adapter is going to be a new PokedexAdapter. 764 00:41:41,370 --> 00:41:44,310 We didn't specify any parameters in the constructor. 765 00:41:44,310 --> 00:41:45,900 That's fine. 766 00:41:45,900 --> 00:41:49,080 Next, we want to create that new layout manager. 767 00:41:49,080 --> 00:41:54,150 Remember, we used a linear layout, so we can just say new LinearLayoutManager. 768 00:41:54,150 --> 00:41:57,120 And then it just needs a reference to the activity. 769 00:41:57,120 --> 00:41:59,070 So there we go. 770 00:41:59,070 --> 00:42:02,800 Now lastly, we want to connect those things. 771 00:42:02,800 --> 00:42:04,725 So we want to say RecyclerView. 772 00:42:04,725 --> 00:42:09,060 We want to set the adapter to be my adapter. 773 00:42:09,060 --> 00:42:16,630 And we want to set our layout manager to be that layout manager. 774 00:42:16,630 --> 00:42:21,900 And so now what we've done is we've instantiated that recycler view. 775 00:42:21,900 --> 00:42:27,610 We've set the adapter for that recycler view to be that adapter that we wrote. 776 00:42:27,610 --> 00:42:31,230 And so now it knows what data to display. 777 00:42:31,230 --> 00:42:36,130 So now let's go ahead and run this project and see what happens. 778 00:42:36,130 --> 00:42:39,180 OK, so it looks like we've got an error here. 779 00:42:39,180 --> 00:42:41,180 So let's check out what that error is. 780 00:42:41,180 --> 00:42:43,390 I can just double quick here. 781 00:42:43,390 --> 00:42:46,520 And it looks like PokedexViewHolder holder has private access. 782 00:42:46,520 --> 00:42:50,310 So, whoops, looks like we mistakenly said public here-- or private. 783 00:42:50,310 --> 00:42:54,682 If we just change this to public, we'll notice that that error goes away. 784 00:42:54,682 --> 00:42:56,390 And this makes sense, because we actually 785 00:42:56,390 --> 00:42:59,090 are using this class outside of the class, 786 00:42:59,090 --> 00:43:01,100 because we're using it in this declaration. 787 00:43:01,100 --> 00:43:03,680 So private didn't actually make sense. 788 00:43:03,680 --> 00:43:06,600 So now let's try running it again. 789 00:43:06,600 --> 00:43:08,500 So it looks like it installed successfully. 790 00:43:08,500 --> 00:43:11,197 So let's pull up our app. 791 00:43:11,197 --> 00:43:12,280 It looks like we're close. 792 00:43:12,280 --> 00:43:15,370 It looks like we have a list with Bulbasaur, Ivysaur, and Venusaur, 793 00:43:15,370 --> 00:43:19,113 but it's kind of weird, because each one only fits sort of, like, one 794 00:43:19,113 --> 00:43:20,030 on the screen at once. 795 00:43:20,030 --> 00:43:23,606 So let's go back to our layout and see why that might be. 796 00:43:23,606 --> 00:43:27,550 Ah, so it looks like we've set the heights to instead 797 00:43:27,550 --> 00:43:30,340 be matching the entire parent. 798 00:43:30,340 --> 00:43:33,730 So instead, we want to just set this to wrap_content, 799 00:43:33,730 --> 00:43:39,940 so that the height of each row is just simply enough space to fit that row. 800 00:43:39,940 --> 00:43:42,250 Instead we're saying the height is the entire screen. 801 00:43:42,250 --> 00:43:46,360 We just want to make the row just big enough to fit everything inside of it. 802 00:43:46,360 --> 00:43:47,800 So that's fixed. 803 00:43:47,800 --> 00:43:49,507 Let's run it again. 804 00:43:49,507 --> 00:43:52,340 And this time you got something a little bit more of what we wanted. 805 00:43:52,340 --> 00:43:58,440 So now we have each row displayed in our pokedex and they're on the screen. 806 00:43:58,440 --> 00:44:02,330 So the next thing we want to do is create a new activity. 807 00:44:02,330 --> 00:44:07,790 And this activity is going to appear when one of these rows is selected. 808 00:44:07,790 --> 00:44:10,730 So let's jump back to Android Studio. 809 00:44:10,730 --> 00:44:17,120 Over here on the left hand side, let's go to new, down here to activity, 810 00:44:17,120 --> 00:44:20,180 and then we're just going to pick an empty activity again, because we're 811 00:44:20,180 --> 00:44:21,805 going to be writing the layout ourself. 812 00:44:21,805 --> 00:44:24,140 813 00:44:24,140 --> 00:44:30,398 So our activity name, let's call it PokemonActivity. 814 00:44:30,398 --> 00:44:32,690 And you'll notice here that we have this checkmark that 815 00:44:32,690 --> 00:44:36,120 enables us to generate a layout file. 816 00:44:36,120 --> 00:44:39,320 So let's leave that checked so that Android Studio rights a little bit 817 00:44:39,320 --> 00:44:41,210 of that boilerplate for us. 818 00:44:41,210 --> 00:44:44,870 Our layout name, we can keep the same, just activity_pokemon. 819 00:44:44,870 --> 00:44:50,870 Don't need to worry about anything else here, so let's click finish. 820 00:44:50,870 --> 00:44:54,320 And the file that's generated here is just like the other files we've seen, 821 00:44:54,320 --> 00:44:56,360 so nothing crazy there. 822 00:44:56,360 --> 00:44:59,540 And you can see that we have a new layout file over here 823 00:44:59,540 --> 00:45:03,350 to the left called activity_pokemon. 824 00:45:03,350 --> 00:45:05,525 So let's close out a few of these other tabs. 825 00:45:05,525 --> 00:45:09,350 826 00:45:09,350 --> 00:45:14,900 And just like we did before, let's start by writing our layout file. 827 00:45:14,900 --> 00:45:17,390 So rather than using a ConstraintLayout, we 828 00:45:17,390 --> 00:45:20,030 can just use a linear layout, since all we're going to do 829 00:45:20,030 --> 00:45:23,580 is display a couple of text views stacked on top of each other. 830 00:45:23,580 --> 00:45:25,710 So let's change this to be a linear layout. 831 00:45:25,710 --> 00:45:30,460 832 00:45:30,460 --> 00:45:31,630 That's all we need there. 833 00:45:31,630 --> 00:45:35,050 We want to make sure that the height and width are both match_parent, 834 00:45:35,050 --> 00:45:37,120 so it can fill the entire screen. 835 00:45:37,120 --> 00:45:42,520 This context that was generated for us, we'd just have that be PokemonActivity. 836 00:45:42,520 --> 00:45:45,770 And then let's make sure the closing tag matches. 837 00:45:45,770 --> 00:45:47,620 And now let's add a couple of text views. 838 00:45:47,620 --> 00:45:54,260 Let's say one going to be wrap_content, so it's just big enough. 839 00:45:54,260 --> 00:45:57,840 Let's give this an ID, because we'll need it. 840 00:45:57,840 --> 00:46:03,960 And we'll give that an idea of pokemon_name. 841 00:46:03,960 --> 00:46:06,600 We can set a couple other attributes while we're here. 842 00:46:06,600 --> 00:46:10,225 For example, we might want to set the text alignment. 843 00:46:10,225 --> 00:46:12,100 So we want to center this text on the screen, 844 00:46:12,100 --> 00:46:14,640 so let's give it a text alignment of center. 845 00:46:14,640 --> 00:46:16,480 And then we might also want to set the size. 846 00:46:16,480 --> 00:46:20,280 So if I just start typing size, I can see textSize. 847 00:46:20,280 --> 00:46:23,610 And we're going to give this a size of 18 dp. 848 00:46:23,610 --> 00:46:28,860 So dp here is a device or density independent pixel. 849 00:46:28,860 --> 00:46:33,000 And this basically is a way of using pixels to specify the size of things. 850 00:46:33,000 --> 00:46:36,365 But on all these different phones with different densities of pixels, 851 00:46:36,365 --> 00:46:38,490 that can kind of get confusing, and so this is just 852 00:46:38,490 --> 00:46:41,190 kind of a way to normalize across all of that. 853 00:46:41,190 --> 00:46:43,340 So we want to just say this is a size of 18. 854 00:46:43,340 --> 00:46:45,840 That's pretty big, but not too big. 855 00:46:45,840 --> 00:46:48,690 And now that's one, so let's just add one other text view. 856 00:46:48,690 --> 00:46:51,570 This is going to be displayed below it. 857 00:46:51,570 --> 00:46:55,030 This time, let's say it's a pokemon_number. 858 00:46:55,030 --> 00:46:56,515 Still want to center it. 859 00:46:56,515 --> 00:46:57,640 Yeah, let's give it a size. 860 00:46:57,640 --> 00:46:59,490 Let's make it a little smaller. 861 00:46:59,490 --> 00:47:04,100 And let's also do something to sort of space things out a bit, 862 00:47:04,100 --> 00:47:05,380 so let's add some padding. 863 00:47:05,380 --> 00:47:10,190 Let's say we have android: paddingTop. 864 00:47:10,190 --> 00:47:14,070 Let's just give this 10 pixels of space there. 865 00:47:14,070 --> 00:47:22,820 And then maybe 5 pixels of space here. 866 00:47:22,820 --> 00:47:26,570 OK, so that's everything we need for the text views. 867 00:47:26,570 --> 00:47:29,030 So the last thing we want to do is specify 868 00:47:29,030 --> 00:47:31,850 that we want our views to be stacked on top of each other, 869 00:47:31,850 --> 00:47:33,560 not next to each other. 870 00:47:33,560 --> 00:47:36,560 So to do that, we're just going to add one more attribute to our layout. 871 00:47:36,560 --> 00:47:40,640 We're going to say the orientation of this layout is vertical, 872 00:47:40,640 --> 00:47:42,480 rather than horizontal. 873 00:47:42,480 --> 00:47:47,250 And so that will nicely give us text views on top of each other. 874 00:47:47,250 --> 00:47:51,710 OK, So now let's return to that Java activity. 875 00:47:51,710 --> 00:47:55,190 So what we want to do when this activity is created 876 00:47:55,190 --> 00:48:01,680 is take some text that's passed into us and display it on the view. 877 00:48:01,680 --> 00:48:05,060 So let's do what we did last time and create a few fields 878 00:48:05,060 --> 00:48:07,230 that represent our text views. 879 00:48:07,230 --> 00:48:13,920 So we have a text view representing our name. 880 00:48:13,920 --> 00:48:19,060 And we have a text view representing our number. 881 00:48:19,060 --> 00:48:21,600 882 00:48:21,600 --> 00:48:27,390 And so now, inside of onCreate is where we want to set those values. 883 00:48:27,390 --> 00:48:30,180 So to get those values, remember that we're 884 00:48:30,180 --> 00:48:33,750 going to use the special object called an intent. 885 00:48:33,750 --> 00:48:38,620 An intent is how we're going to pass data from one activity to the other. 886 00:48:38,620 --> 00:48:41,370 So let's write the second half first. 887 00:48:41,370 --> 00:48:44,400 To get the intent that started this activity, 888 00:48:44,400 --> 00:48:46,620 you just have to call getIntent. 889 00:48:46,620 --> 00:48:51,830 And this is a method that's defined somewhere in AppCompat activity. 890 00:48:51,830 --> 00:48:53,590 And so we can just use it. 891 00:48:53,590 --> 00:49:00,330 So we can say getIntent and getStringExtra. 892 00:49:00,330 --> 00:49:03,840 And so this is saying I want to get some of the extra data that 893 00:49:03,840 --> 00:49:05,810 was passed along from this intent. 894 00:49:05,810 --> 00:49:07,990 And I want to get it as a string. 895 00:49:07,990 --> 00:49:11,490 And so let's say I want the string called name. 896 00:49:11,490 --> 00:49:14,880 And I'm going to store that in a variable called name. 897 00:49:14,880 --> 00:49:20,870 Similarly, let's grab the number, so we'll say int number is getIntent. 898 00:49:20,870 --> 00:49:24,920 And rather than a string extra, we want to get an int extra. 899 00:49:24,920 --> 00:49:27,030 Say that's the number. 900 00:49:27,030 --> 00:49:30,840 And then with int, we also have to specify some default value, 901 00:49:30,840 --> 00:49:33,570 in case it's not passed in, so we'll just say 0, 902 00:49:33,570 --> 00:49:38,100 but we're always going to pass this in, so we're not that worried about it. 903 00:49:38,100 --> 00:49:42,490 Lastly, let's set the contents of those text views. 904 00:49:42,490 --> 00:49:44,760 So let's say nameTextView. 905 00:49:44,760 --> 00:49:47,240 Let's use that findViewById again. 906 00:49:47,240 --> 00:49:52,710 But here we're used to this R.id dot, we called it, pokemon_name. 907 00:49:52,710 --> 00:50:02,110 And our numberTextView, we called that pokemon_number. 908 00:50:02,110 --> 00:50:05,210 And so last, we can just call that same set text method, 909 00:50:05,210 --> 00:50:07,100 the same one that we've called before. 910 00:50:07,100 --> 00:50:09,206 And we'll say nameTextView.setText(name). 911 00:50:09,206 --> 00:50:13,340 912 00:50:13,340 --> 00:50:17,390 And then numberTextView.setText. 913 00:50:17,390 --> 00:50:19,730 And then we also, right now, we have an int. 914 00:50:19,730 --> 00:50:22,070 And we want to create a string. 915 00:50:22,070 --> 00:50:29,340 So we can just say Integer.toString, pass in that int, 916 00:50:29,340 --> 00:50:33,212 and so this will just nicely convert an int to a string. 917 00:50:33,212 --> 00:50:34,670 And so that's it for this activity. 918 00:50:34,670 --> 00:50:35,650 It's pretty simple. 919 00:50:35,650 --> 00:50:37,230 We're not doing too much. 920 00:50:37,230 --> 00:50:39,990 We're just taking some data that we received from our intent 921 00:50:39,990 --> 00:50:42,630 and we're displaying it. 922 00:50:42,630 --> 00:50:46,560 So now let's set the first half of this interaction, 923 00:50:46,560 --> 00:50:51,690 which is how we pass data from the first activity to the second. 924 00:50:51,690 --> 00:50:55,560 So to do that, I'm going to jump back into my pokedex adapter. 925 00:50:55,560 --> 00:51:00,990 By the way, to jump around quickly in Android Studio, if you hit shift shift, 926 00:51:00,990 --> 00:51:02,790 you can get this nice little search field 927 00:51:02,790 --> 00:51:06,387 where you can search for file names or classes or really whatever. 928 00:51:06,387 --> 00:51:08,220 So that's kind of a nice way to jump around. 929 00:51:08,220 --> 00:51:10,830 930 00:51:10,830 --> 00:51:16,180 So let's think about how we can pass along this pokemon data. 931 00:51:16,180 --> 00:51:20,160 So we know that we have the Pokemon that we want to pass inside 932 00:51:20,160 --> 00:51:22,718 of this onBindViewHolder method. 933 00:51:22,718 --> 00:51:25,260 And really, it doesn't look like anywhere else in this class, 934 00:51:25,260 --> 00:51:26,730 I have access to that. 935 00:51:26,730 --> 00:51:28,880 The view holder takes in a view. 936 00:51:28,880 --> 00:51:30,880 All these other methods don't have any position. 937 00:51:30,880 --> 00:51:33,990 So we know that we have to add it here. 938 00:51:33,990 --> 00:51:40,770 And so we want some way to pass along this object to our view holder. 939 00:51:40,770 --> 00:51:45,720 And luckily, view holder has a nice method that's built in here. 940 00:51:45,720 --> 00:51:49,420 I can say, I have my containerView. 941 00:51:49,420 --> 00:51:52,500 And I want to call something called setTag. 942 00:51:52,500 --> 00:51:56,750 And a tag is basically just some object that's associated with the view. 943 00:51:56,750 --> 00:52:00,930 A tag can be anything, which is nice, because we have this pokemon object 944 00:52:00,930 --> 00:52:02,680 that we want to send along. 945 00:52:02,680 --> 00:52:06,010 So let's just set that as the tag. 946 00:52:06,010 --> 00:52:10,890 So now our view holder has access to its current pokemon. 947 00:52:10,890 --> 00:52:15,360 So now that we have access to the current pokemon from the view holder, 948 00:52:15,360 --> 00:52:20,460 let's add an event handler that can be executed when the row is tapped. 949 00:52:20,460 --> 00:52:24,240 To do that, we're going to say containerView.setOnClickListener. 950 00:52:24,240 --> 00:52:27,120 951 00:52:27,120 --> 00:52:29,700 And this is going to take one argument that's 952 00:52:29,700 --> 00:52:32,670 going to be an instance of a class. 953 00:52:32,670 --> 00:52:34,830 But we're only going to use this instance once, 954 00:52:34,830 --> 00:52:36,930 so we can use this nice Java syntax. 955 00:52:36,930 --> 00:52:41,060 We can say [INAUDIBLE] View.onClickListener. 956 00:52:41,060 --> 00:52:44,970 And we're going to do here is write in line, we're going to define the class, 957 00:52:44,970 --> 00:52:46,530 and then instantiate it. 958 00:52:46,530 --> 00:52:49,470 So it looks like this class just has one method. 959 00:52:49,470 --> 00:52:50,760 It's called onClick. 960 00:52:50,760 --> 00:52:54,270 And it's the view that was clicked. 961 00:52:54,270 --> 00:52:56,850 So let's first get that pokemon. 962 00:52:56,850 --> 00:53:05,667 So we can say Pokemon current is equal to my containerView.getTag. 963 00:53:05,667 --> 00:53:07,500 But you'll notice here from the autocomplete 964 00:53:07,500 --> 00:53:10,080 that getTag returns an object. 965 00:53:10,080 --> 00:53:13,770 And so we just need to cast that to a pokemon. 966 00:53:13,770 --> 00:53:18,360 We know that when we called setTag, we set that to be an instance of pokemon, 967 00:53:18,360 --> 00:53:21,600 so we can safely cast without a problem here. 968 00:53:21,600 --> 00:53:24,880 So next we want to create an intent object. 969 00:53:24,880 --> 00:53:32,370 So let's go ahead and do that and say intent is a new Intent. 970 00:53:32,370 --> 00:53:35,950 And now this is going to take a couple of arguments. 971 00:53:35,950 --> 00:53:40,107 The first argument is just that context object we saw before. 972 00:53:40,107 --> 00:53:41,440 Don't worry too much about that. 973 00:53:41,440 --> 00:53:43,840 You can just say getContext. 974 00:53:43,840 --> 00:53:46,620 And then the second argument it's going to take 975 00:53:46,620 --> 00:53:49,710 is what class we want to instantiate. 976 00:53:49,710 --> 00:53:53,770 So we want to instantiate our new pokemon activity. 977 00:53:53,770 --> 00:53:55,920 So we're going to say PokemonActivity.class. 978 00:53:55,920 --> 00:53:58,780 979 00:53:58,780 --> 00:54:02,680 Now that we have our intent, we want to set those extras, 980 00:54:02,680 --> 00:54:05,350 since we know that we were getting them before. 981 00:54:05,350 --> 00:54:09,250 So we're going to say intent.putExtra. 982 00:54:09,250 --> 00:54:14,800 We want to say our name is our current.getName. 983 00:54:14,800 --> 00:54:25,368 And then we want to say our number is getNumber. 984 00:54:25,368 --> 00:54:26,910 So that's it for creating the intent. 985 00:54:26,910 --> 00:54:27,910 It's pretty simple. 986 00:54:27,910 --> 00:54:30,900 It's just saying here's an activity I want to go to 987 00:54:30,900 --> 00:54:34,500 and here's some data that I want to pass along to that activity. 988 00:54:34,500 --> 00:54:38,550 And so now the last thing to do is just to call 989 00:54:38,550 --> 00:54:41,100 start an activity with that intent. 990 00:54:41,100 --> 00:54:50,870 So I can say getContext().startActivity and pass along my intent. 991 00:54:50,870 --> 00:54:54,260 So now, let's go ahead and try running this. 992 00:54:54,260 --> 00:54:58,670 Looks like my install worked, so let's jump to the Android emulator. 993 00:54:58,670 --> 00:55:00,570 Here's our recycler view as before. 994 00:55:00,570 --> 00:55:03,340 Now let's tap on Bulbasaur here. 995 00:55:03,340 --> 00:55:04,130 And there we go. 996 00:55:04,130 --> 00:55:09,260 It looks like we're now displaying our second activity with that information. 997 00:55:09,260 --> 00:55:11,900 Just to be sure, let's try tapping on Venusaur. 998 00:55:11,900 --> 00:55:17,240 And it looks like we're successfully passing data back and forth. 999 00:55:17,240 --> 00:55:21,080 But now, when we look at this recycler view, it's kind of smushed 1000 00:55:21,080 --> 00:55:23,720 and doesn't really look like a lot of Android applications do. 1001 00:55:23,720 --> 00:55:25,553 When you start tapping on something, there's 1002 00:55:25,553 --> 00:55:28,610 no indication that anything happened. 1003 00:55:28,610 --> 00:55:32,130 So let's make this recycler view look a little bit nicer. 1004 00:55:32,130 --> 00:55:38,040 So to do that, let's jump back to the activity for our recycler view. 1005 00:55:38,040 --> 00:55:39,480 So this is our main activity. 1006 00:55:39,480 --> 00:55:43,820 Remember, we added this recycler view with a row of pokemon_row. 1007 00:55:43,820 --> 00:55:46,950 So we're back here. 1008 00:55:46,950 --> 00:55:51,210 So the first thing we want to do is add a little bit of padding to each row. 1009 00:55:51,210 --> 00:55:58,230 So just like we did before, let's say, it has a padding of 10 pixels. 1010 00:55:58,230 --> 00:56:01,130 And so this will automatically add padding to the top, bottom, left 1011 00:56:01,130 --> 00:56:03,260 and right, so that's nice. 1012 00:56:03,260 --> 00:56:06,350 We also want to indicate to the user that it's clickable. 1013 00:56:06,350 --> 00:56:09,830 So we're going to set clickable to true and we're 1014 00:56:09,830 --> 00:56:11,705 going to set focusable to true. 1015 00:56:11,705 --> 00:56:15,250 1016 00:56:15,250 --> 00:56:17,000 So those are just sort of ways to indicate 1017 00:56:17,000 --> 00:56:18,583 that you can actually tap on this row. 1018 00:56:18,583 --> 00:56:20,690 They're not just statically presenting data. 1019 00:56:20,690 --> 00:56:23,928 Now the last attribute I want to add is that nice effect 1020 00:56:23,928 --> 00:56:25,970 you see on Android when you tap a row and there's 1021 00:56:25,970 --> 00:56:27,980 that sort of ripple effect on the background. 1022 00:56:27,980 --> 00:56:31,250 We can actually get that for free without writing a lot of animation 1023 00:56:31,250 --> 00:56:32,180 ourself. 1024 00:56:32,180 --> 00:56:36,165 We can just say android: foreground. 1025 00:56:36,165 --> 00:56:38,290 And then we're going to use this interesting syntax 1026 00:56:38,290 --> 00:56:39,940 to access some of those built-ins. 1027 00:56:39,940 --> 00:56:45,140 We're going to say android: attr, which is short for attribute. 1028 00:56:45,140 --> 00:56:49,060 And so now, if I just start typing, I can see a bunch of different things 1029 00:56:49,060 --> 00:56:49,780 I can access. 1030 00:56:49,780 --> 00:56:53,240 The one that I want is called selectable item background. 1031 00:56:53,240 --> 00:56:55,330 And this just sort of adds that nice animation 1032 00:56:55,330 --> 00:56:58,090 to the row when you tap on it. 1033 00:56:58,090 --> 00:57:02,410 So I also noticed when I ran it, that the text on that second activity 1034 00:57:02,410 --> 00:57:03,490 wasn't centered. 1035 00:57:03,490 --> 00:57:07,435 So let's take a look at why that might be. 1036 00:57:07,435 --> 00:57:10,990 If we jump over here to text, you'll notice here 1037 00:57:10,990 --> 00:57:13,720 that we set both the width and the height 1038 00:57:13,720 --> 00:57:17,020 to wrap_content, which means that the width is only 1039 00:57:17,020 --> 00:57:19,960 going to be big enough to fit the text. 1040 00:57:19,960 --> 00:57:22,990 And because of that, we haven't actually centered anything. 1041 00:57:22,990 --> 00:57:26,300 We're basically saying it's centered, but it's only with-- 1042 00:57:26,300 --> 00:57:28,120 you know, it's only a third of the screen, 1043 00:57:28,120 --> 00:57:30,490 so it's not actually centered within the screen. 1044 00:57:30,490 --> 00:57:35,140 So to do that, I instead want to set match_parent here. 1045 00:57:35,140 --> 00:57:37,840 And this says that we want the container for the text view 1046 00:57:37,840 --> 00:57:41,050 to fill the whole screen and then center within that. 1047 00:57:41,050 --> 00:57:44,320 So that means it's actually going to be centered on the screen. 1048 00:57:44,320 --> 00:57:47,920 So those changes let's try running it again. 1049 00:57:47,920 --> 00:57:50,170 My install worked, so let's open it up. 1050 00:57:50,170 --> 00:57:51,190 This looks a bit nicer. 1051 00:57:51,190 --> 00:57:53,020 So there's my padding coming into play. 1052 00:57:53,020 --> 00:57:54,850 It's not squished anymore. 1053 00:57:54,850 --> 00:57:56,400 Now let's try selecting a row. 1054 00:57:56,400 --> 00:57:58,480 You can see I had that nice ripple effect. 1055 00:57:58,480 --> 00:58:01,030 I didn't have to do anything to get that. 1056 00:58:01,030 --> 00:58:03,940 And now my text is actually centered. 1057 00:58:03,940 --> 00:58:07,690 So let's add one more finishing touch to this pokedex activity 1058 00:58:07,690 --> 00:58:09,040 before we're done. 1059 00:58:09,040 --> 00:58:11,830 Rather than displaying the number 2, let's display it 1060 00:58:11,830 --> 00:58:15,790 as an actual pokedex would, where the number is padded with zeros, 1061 00:58:15,790 --> 00:58:17,930 so it's always a three digit number. 1062 00:58:17,930 --> 00:58:22,150 So to do that I'm going to come back to my PokemonActivity. 1063 00:58:22,150 --> 00:58:26,680 Rather than just setting the text to this Integer.toString(number), 1064 00:58:26,680 --> 00:58:30,370 I'm going to use a method called string.format that's basically 1065 00:58:30,370 --> 00:58:32,950 equivalent to printf() in C. 1066 00:58:32,950 --> 00:58:36,250 So I'm going to say string.format. 1067 00:58:36,250 --> 00:58:39,650 And just like printf(), this is going to take two arguments. 1068 00:58:39,650 --> 00:58:42,160 The first one is my format string. 1069 00:58:42,160 --> 00:58:45,340 So remember that in order to pad zeros to something, 1070 00:58:45,340 --> 00:58:50,680 I can just say %03d and that'll say, give me an integer that's padded with-- 1071 00:58:50,680 --> 00:58:52,030 it has always three digits. 1072 00:58:52,030 --> 00:58:54,020 It's padded with zeros if not. 1073 00:58:54,020 --> 00:58:56,050 And then my other argument is just the integer 1074 00:58:56,050 --> 00:58:59,050 I want to format, which is number. 1075 00:58:59,050 --> 00:59:02,590 So same exact print syntax as printf. 1076 00:59:02,590 --> 00:59:08,210 So if I add that and run my app one last time, we've installed successfully. 1077 00:59:08,210 --> 00:59:11,260 If I tap on the row, I'm now getting everything 1078 00:59:11,260 --> 00:59:14,020 formatted the way I wanted it to be. 1079 00:59:14,020 --> 00:59:16,600 So that's it for our simple pokedex app. 1080 00:59:16,600 --> 00:59:20,590 Next, we're going to take a look at how to dynamically add information 1081 00:59:20,590 --> 00:59:24,120 to this app, rather than hard coding it. 1082 00:59:24,120 --> 00:59:25,121