1 00:00:00,640 --> 00:00:04,250 Let's take a look at what we're going to need in order to add a list 2 00:00:04,250 --> 00:00:05,010 to our list fragment. 3 00:00:06,190 --> 00:00:09,560 First, instead of the Text View, our fragment's layout should 4 00:00:09,560 --> 00:00:14,250 probably have a ListView, or even better, a RecyclerView. 5 00:00:14,250 --> 00:00:17,900 Then will need an adapter to help manage the views in our list, and 6 00:00:17,900 --> 00:00:21,150 we'll also need a layout for what we want our list items to look like. 7 00:00:22,740 --> 00:00:25,380 Let's start with the layout for our list item. 8 00:00:25,380 --> 00:00:33,390 In the layout folder, let's create a new layout resource file named list_item. 9 00:00:33,390 --> 00:00:34,610 Remember from the mockups, 10 00:00:34,610 --> 00:00:39,200 that each list item is a picture of the recipe followed by its name. 11 00:00:39,200 --> 00:00:45,090 So let's drag out an image view, and then a text view. 12 00:00:47,410 --> 00:00:49,200 Then I'm going to switch to the text tab. 13 00:00:49,200 --> 00:00:53,070 And if you want to open a preview like this 14 00:00:53,070 --> 00:00:56,030 just hit the preview button over here on the right. 15 00:00:56,030 --> 00:00:59,860 Next let's change the orientation of the linear layout to horizontal. 16 00:01:02,190 --> 00:01:04,160 Change its layout height to wrap content. 17 00:01:08,810 --> 00:01:11,810 And give our two new views better IDs. 18 00:01:11,810 --> 00:01:17,510 Let's name the image view, item image and the text view, item text. 19 00:01:20,180 --> 00:01:22,910 To make the text view take up most of the width, 20 00:01:22,910 --> 00:01:25,750 let's change both layout width properties to 0dp. 21 00:01:25,750 --> 00:01:31,510 0dp for the TextView, and 0dp for the ImageView. 22 00:01:32,970 --> 00:01:35,400 And let's give our ImageView a layout_weight of 1. 23 00:01:35,400 --> 00:01:41,869 And the TextView a layout_weight of 3. 24 00:01:45,189 --> 00:01:46,070 Looking good, 25 00:01:46,070 --> 00:01:50,220 now let's finish off the image view by setting layout height to 50dp. 26 00:01:53,180 --> 00:01:58,040 Then let's add the scale type attribute and set it equal to fitCenter 27 00:01:59,820 --> 00:02:04,280 and let's set layout_margin to 8dp to add some padding. 28 00:02:05,700 --> 00:02:08,080 Setting the layout height to 50dp and 29 00:02:08,080 --> 00:02:12,140 the scaleType to fitCenter means that our images will be 50dp tall. 30 00:02:12,140 --> 00:02:15,200 And they will be scaled to fit nicely inside our image view. 31 00:02:16,550 --> 00:02:20,910 Lastly, let's finish off our text view by setting layout margin to 12dp. 32 00:02:27,029 --> 00:02:29,400 And text size to 24 sp. 33 00:02:36,760 --> 00:02:39,460 Now that we're done with our layout for our list item, 34 00:02:39,460 --> 00:02:44,250 let's create the adapter which will serve up these list items to our recycler view. 35 00:02:44,250 --> 00:02:49,010 Let's make a new class and name it ListAdapter 36 00:02:51,750 --> 00:03:01,520 and make it extend RecyclerView.Adapter, which doesn't seem to exist. 37 00:03:01,520 --> 00:03:03,500 Over in our apps, build.Gradle file 38 00:03:06,710 --> 00:03:09,970 let's add the RecyclerView support library as a dependency. 39 00:03:11,320 --> 00:03:14,310 You can just copy and paste the code from the teacher's notes if you'd like. 40 00:03:17,810 --> 00:03:18,660 Then hit Sync Now. 41 00:03:18,660 --> 00:03:23,170 And then, we can close the build.gradle file. 42 00:03:24,920 --> 00:03:30,050 Back in our list adapter class lets use alt enter to import the recycler view. 43 00:03:31,420 --> 00:03:34,950 Then lets use alt enter again to implement the required methods. 44 00:03:36,660 --> 00:03:40,750 But before we get to these methods we should probably create our view holder 45 00:03:40,750 --> 00:03:42,280 class. 46 00:03:42,280 --> 00:03:46,560 At the bottom of this class, let's create a new private class, 47 00:03:50,500 --> 00:03:51,950 named ListViewHolder. 48 00:03:54,070 --> 00:04:01,220 And let's make it extend the RecyclerView.Viewholder class. 49 00:04:03,620 --> 00:04:07,630 And let's also implement the View.OnClickListener interface. 50 00:04:14,830 --> 00:04:18,405 When we tap on the list item, we want it to show us that recipe, so 51 00:04:18,405 --> 00:04:19,500 we'll need an OnClickListener. 52 00:04:21,290 --> 00:04:24,000 Then let's use Alt + Enter to create the onClick method. 53 00:04:27,030 --> 00:04:29,190 And let's use it again to create the constructor. 54 00:04:32,410 --> 00:04:35,910 Next, let's create a field for each of the views in our listItem. 55 00:04:41,008 --> 00:04:46,012 Private TextView, we'll call it mTextView. 56 00:04:46,012 --> 00:04:50,380 Alt enter to import TextView and 57 00:04:50,380 --> 00:04:54,921 private ImageView mImageView. 58 00:04:56,380 --> 00:04:58,408 And let's set these fields in the constructor. 59 00:04:58,408 --> 00:05:07,550 mTextView = itemView.findViewById(R.id.itemText). 60 00:05:07,550 --> 00:05:16,070 Alt enter to add the cast. 61 00:05:19,430 --> 00:05:21,791 And then mImageView = 62 00:05:21,791 --> 00:05:29,011 itemView.findViewById(R.id.itemImage) equals item view. 63 00:05:29,011 --> 00:05:31,670 And alt enter to add the cast. 64 00:05:32,750 --> 00:05:34,520 Then let's finish off the constructor, 65 00:05:34,520 --> 00:05:37,955 by setting our view holder as the itemViews on ClickListener. 66 00:05:37,955 --> 00:05:46,420 ItemView.setOnClickListener and pass and this. 67 00:05:47,810 --> 00:05:50,950 All right, let's get back to our list adapter methods 68 00:05:50,950 --> 00:05:52,570 starting with onCreateViewHolder. 69 00:05:53,990 --> 00:05:59,220 Since we need to return a ViewHolder let's start by returning a new list view holder. 70 00:06:02,450 --> 00:06:05,020 Which requires a view as a parameter. 71 00:06:05,020 --> 00:06:08,970 So let's pass in the word view, and 72 00:06:08,970 --> 00:06:11,930 then use alt enter to create it as a local variable. 73 00:06:14,310 --> 00:06:19,030 To get our view we'll need to inflate it just like we did with our fragment. 74 00:06:19,030 --> 00:06:25,551 Let's set it equal to layoutinflator.from and 75 00:06:25,551 --> 00:06:30,670 pass in parent.getcontext. 76 00:06:30,670 --> 00:06:32,608 Then, now that we've got our inflater. 77 00:06:32,608 --> 00:06:38,000 Let's call .inflate and pass in our list 78 00:06:38,000 --> 00:06:42,790 item layout R.layout.listitem. 79 00:06:42,790 --> 00:06:46,561 The parent view group. 80 00:06:46,561 --> 00:06:47,813 Parent. 81 00:06:49,180 --> 00:06:50,810 And false. 82 00:06:50,810 --> 00:06:54,530 Since this time we really don't want to attach our view to the parent view group. 83 00:06:55,930 --> 00:07:00,630 Moving onto onBindViewHolder this is where we should update the view and 84 00:07:00,630 --> 00:07:04,030 our view holder to reflect which position it's in on the screen. 85 00:07:05,720 --> 00:07:09,930 And since we can't do this with the list view holder class we have now, 86 00:07:09,930 --> 00:07:12,766 let's add a bindView method to our list ViewHolder. 87 00:07:12,766 --> 00:07:20,890 public void bindView. 88 00:07:20,890 --> 00:07:23,280 And it takes on a position. 89 00:07:25,430 --> 00:07:28,600 Inside this method, we'll need to update our TextView and 90 00:07:28,600 --> 00:07:30,910 ImageView to display the right recipe. 91 00:07:32,240 --> 00:07:37,080 Luckily, our Recipe class has an array for the recipe names, and an array for 92 00:07:37,080 --> 00:07:40,875 the resource IDs of the images, so this isn't too difficult. 93 00:07:40,875 --> 00:07:46,060 mTextView.setText and 94 00:07:46,060 --> 00:07:50,250 passing in Recipes.names. 95 00:07:50,250 --> 00:07:57,490 At index position will take care of the text view. 96 00:07:57,490 --> 00:08:02,280 And mImageView.setImageResource, and 97 00:08:02,280 --> 00:08:06,936 passing in Recipe.resourceIds at index 98 00:08:06,936 --> 00:08:11,730 position will take care of the image view. 99 00:08:13,370 --> 00:08:17,200 Now that that's done let's call this method from OnbindView holder. 100 00:08:18,360 --> 00:08:22,530 First we'll need to cast the holder parameter to a list view holder. 101 00:08:23,740 --> 00:08:30,570 So two left parentheses list view holder Which is going to be the cast, 102 00:08:30,570 --> 00:08:35,180 and we're casting our holder, which is now a ListViewHolder, and 103 00:08:35,180 --> 00:08:38,820 then we can call .bindView, and pass along the position. 104 00:08:40,700 --> 00:08:44,225 Last but not least, let's update getItemCount to return 105 00:08:44,225 --> 00:08:49,410 Recipes.names.length. 106 00:08:49,410 --> 00:08:52,290 For this app, the recipes are totally static and 107 00:08:52,290 --> 00:08:56,220 will never change, so it's okay to use the names array when setting the item count.