1. Home
  2. Training Library
  3. Programming
  4. Programming Courses
  5. Classes, Objects, OOP, and RecyclerView for Android

Bind Data to Viewholders

Start course
Overview
Difficulty
Intermediate
Duration
3h 12m
Students
2
Description

The course covers Recycler Views, which is one of the most important features of Android app development. They allow us to work with lists or grids of data with a ton of built-in optimizations. We'll then put your knowledge into practice by building an app to display a list of posts that we can scroll through, edit them, delete them, etc.

We'll also explore object-oriented programming with Kotlin, focusing on how to build objects, work with inheritance concepts and interfaces, and other highly advanced features. You'll also learn about classes and objects and how to work with them with the Kotlin programming language.

Intended Audience

This course is intended for beginners to Android app development or anyone who wants to master coding in Kotlin.

Prerequisites

Since this is a beginner level course, there are no requirements, but any previous experience with coding would be beneficial.

Transcript

Hello and welcome back. In this video, we will take the properties of our post-object right here, these properties which we are creating over here, a list of post-objects, bind their values to the view where we'll display each post. So, this view right here. You see, we have an ImageView, this is the image, and then the TextView for the title, and then for the body. Let's quickly go ahead and update the IDs for these. So, it's more useful to us. I'll call this 'icon_image_view,' then I'll scroll down to the view. This one is the title. But notice what happened. Because this is constrained to the ImageView, this is now moved off the screen. Whatever the idea was for the ImageView. 

So, right here in my constraints— top to the top of— I have to change this to 'icon_image_view.' So, right here, 'icon_image_view.' Similarly, I have to do it for this 'icon_image_view.' There we go. And here, constraint bottom to the top of, that's the TextView too. So, I'm going to change this next TextView with the ID of body, and then bottom to the top of, this one is going to be body right here, okay? And over here, this one, bottom to the bottom of, this one I'll change to 'icon_image_view' as well, along with this. 'icon_image_view.' 

Okay, now that that's done, you see it's looking much better, and the edit and delete actions, right here- I'm actually just going to get rid of this one because I don't really need it for anything. So, I'll get rid of this for now, okay. So, this is the view. Now, using our PostAdapter over here, with the help of the adapter and the ViewHolder, we can let our app know what values to put in here. You see, we have view— this text— title of our blog post, body of our blog post, and then the image, the source, which one to use. So, all of this, how to fill that in? We're going to implement that in our adapter, okay.

So, let's get started. If you look at our ViewHolder right here, which is the PostViewHolder, this represents one object in our list of post-objects. Okay, think of this as one of these, a view holder for one of these. So, each of these blog posts individually— one— each row is represented by a PostViewHolder. So, what we want to do in our PostViewHolder is include references to each of the views in our post view. So, right here, we have TextView title, body, and icon ImageView. We want to keep a reference to these in the view holder. And we are getting this view, we are getting the whole row view right here in our adapter in this view object: this post-view object of type view. 

So, we can do something like this. We can simply set it by saying, let me call it 'iconImage' for the image. I have to specify what type it is, so it's 'ImageView' right there, and I'll set it equals to postView, which is the view that's getting passed in as parameter, 'findViewByID', and then 'R.ID.' There we go, 'icon_image_view,' all right. So, I'm setting the reference for the image over here, then the text for title. So, val, I'll call it title, of type TextView, right there. Again, if you check over here, there was the ImageView; this is TextView. 

Next one is also 'TextView = postView.findViewByID(R.ID.)' This one was 'title.' And then similarly, 'val_body: TextView = postView.findViewByID (R.ID.body.) And that's it for the method, and this is actually a big optimization since we're only caching these references and are going to be reusing them. So, each PostViewHolder object will keep a reference to these three fields. And when the recycling happens, it will just reuse the references. And this is one of the big optimizations that recycler view brings in, in how we work with lists such as this.

So, you may be asking, "Okay, these are references that are getting cached, but what's actually filling in the data for these? Because these are just the references. We need to actually have an image, and a title, and a body to display for each one of them. Where do we do that? Where do we bind the data for each one of these fields?" And that happens in the onBindViewHolder method right here, which we had left empty before. And this gets called over and over again, every time we have a post to display on the screen. So, as we scroll every time, each one of these references that we have for each ViewHolder will need the data for that particular post to be attached or bound to that row. 

And that's what this onBindViewHolder does. And because of that, because it gets called so many times, you have to be careful about what code you put in here. And if you look in the method, we have this holder parameter that's getting passed in, and this is off type PostViewHolder, which is what we created over here, which is our ViewHolder. And that's the holder for which we have to set the image, the title, and the body.

And let me show you real quick how we can manipulate this. I can simply say, 'holder.iconImage,' right there. And I can set the image resource to be something else. So, let me see what it is right now. Over here, I believe the account, so what I can do is set it to one of these. Let's say 'add_photo.' Let's say 'R.drawable.add_photo.' And then, I can set the title. So, 'holder.title,' and I can set the text so '.text = Some test title, and holder.body.text = Some test body text.' And if I did this, it will set all the default values or reset all the default values that we have set here. So, let's quickly run it and make sure that it works. I'm going to go to app, make sure that this is all set. 

Apply changes and re-run. And there you go. Now you see all of the values have changed. Now we have some test title. Some test body text, which we have just said here, and the image has changed as well. So, that's how we're going to change it. But how do we update it for each one to be different with the different values of the different objects that we have? Well, there's this other parameter over here, the position, and this position indicates which index— so, which one over here— to update? Basically, the position will let the method know which of our road data to get from our data source and set the values here based on that. So, where is the list of data to work with?

As you can see, in our adapter right here, we don't have access to our list anywhere. The dummy list that we're creating in our MockDatabase, we have the ability to create MockData, but we don't have access to this anywhere here. And the PostAdapter is something we're calling from main activity. Right here, we're setting the adapter to PostAdapter. What we have to do is create our list of dummy data. So, our list of objects, and then past that here, as a parameter to PostAdapter. So, then PostAdapter will be able to work with that list of post-objects. So, let's go ahead and create our list over here of dummy data. I'll call it 'val dummyList =' I'll call my method 'createMockData.' There we go. And it's red. I have to import it. There we go. And all that does is it imports the MockDatabase class that we had created. This one, and the companion object within it. So, right there. Now I can use this in my main activity. So, I can simply say, 'dummyList = createMockdata.' And then 'dummyList' will basically be 30 post-objects that we're creating here, and I will pass this to my PostAdapter, this list of post-objects. And if I hover over it, you see it says, "Too many arguments for public constructor PostAdapter." It's because right now, my PostAdapter is not accepting any parameters over here. It has no ability to do that. So I have to add this ability to my PostAdapter to accept this list as a parameter. This or any other list that we're working with.

So, I'll add a constructor here and say, 'val...' I'll call it 'dummyData' over here. This will be a list, and the type for each object in the list will be 'Post,' okay? So, our PostAdapter can now accept a list of post objects to work with. And what that means is now we have a list of dummy data that we are creating over here, and we'll be able to take that data and do whatever we want within here. And as it stands now, we're going to have 30 post-objects or 30 rows of data that we can work with. So, back to our onBindViewHolder. 

I can reference this dummyData list. So, I'll grab, let's call it 'currentPost,' and I'll set it to my dummyData, which is our list at the position that's getting passed in right here. So, 'currentPost' will be the post in my dummyList whose values outset in my holder objects: I image, title, and body. So, here, instead of our draw of all this, I will basically say 'currentPost.iconImage' because remember, this is a post-object right? That I'm grabbing from my generated dummy data. Title, similarly, currentPost.title.' And body: 'currentPost.body.' And another thing I'll do right here. Get item count. I'm saying, 'return 30,' I'm hard coding this.

But what if my list had 500 items? Then I don't want to keep this hard-coded at 30. What I'll do is instead return my dummy data's size, the list size. So, 'dummyData.size.' So, if the list happens to be 500, then this will return 500, which in turn will display 500 items over here. So, let's run it and make sure everything works. And there you go. See, all the rows now have different images. I have different titles and different bodies for them. Check it out. I can scroll up and down and check out the numbers. I can go up. Starts all the way from zero, and goes all the way to 29. So, if I had 500 that I created, it would go all the way to 500 or whatever else. If I had a different data source which was like a database table or something else, it would update based on that.

Okay so, that's a lot that we've covered in this video, and over the past couple of videos, in setting up this adapter, and now binding data to my view holder for each rope. And you might find a lot of it still confusing, but just know that this is probably the most difficult part of implementing and developing a recycler view from scratch. Also, if you do it a few times, it will get embedded in your brain, and each time, it will be easier. 

And the next step for us is to implement the edit and delete functionality. And if you wanted to update the view— so each one could be a different view — then I will leave that as optional. I'll probably add it as a card view later on. But for now, the next step would be to add the edit and delete images over here, so we can implement, edit, and delete functionality for each of our posts. And we'll do that by using on-click listeners. I hope you're excited, and I'll see you in the next video.

 

About the Author

Mashrur is a full-time programming instructor specializing in programming fundamentals, web application development, machine learning and cyber security. He has been a technology professional for over a decade and has degrees in Computer Science and Economics. His niche is building comprehensive career focused technology courses for students entering new, complex, and challenging fields in today's technology space.

Covered Topics