Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Introduction to Android App Development With Kotlin: Recycler Adapter (Part 12)

DZone 's Guide to

Introduction to Android App Development With Kotlin: Recycler Adapter (Part 12)

Check out the final installment of this series on building Android apps with Kotlin.

· Java Zone ·
Free Resource

In the pursuit to display data from the database on screen for the users, we had to overcome a number of challenges, setting up a database, storing items, fetching items, creating a RecyclerView, and many more along the way. After all of this strenuous work, we are almost ready to complete this task. As per the latest tutorial, we must now implement an adapter for the RecyclerView.

So, what is an adapter?

RecyclerAdapter

Recycler Adapter is a class that extends RecyclerView.Adapter. As per Android’s official documentation:

“This object creates views for items, and replaces the content of some of the views with new data items when the original item is no longer visible.”

Equipped with this basic knowledge, we are ready to start implementing your first Recycler Adapter. Create a new Kotlin class and name it MovieRecyclerAdapter. Let’s make this class accept a list of movies that we want to be displayed. Naturally, let’s not forget to make it extend RecyclerView.Adapter . This is what the class header should look like when you’re done.

class MovieRecyclerAdapter(private val myDataset: List<Movie>) :
    RecyclerView.Adapter<MovieRecyclerAdapter.MovieViewHolder>() 


Notice that we pass a type to RecyclerView.Adapter class. The type is a view holder, which is another class we must implement. It extends RecyclerView.ViewHolder. For convenience, we’ll make it a subclass of the adapter class (MovieRecyclerAdapter) because we do not plan on employing it anywhere else.

class MovieViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var tvName: TextView = itemView.findViewById(R.id.tvName)
}


This MovieViewHolder class will allow us to access the view for each cell in the list. Your adapter should look like this so far:

class MovieRecyclerAdapter(private val myDataset: List<Movie>) :
    RecyclerView.Adapter<MovieRecyclerAdapter.MovieViewHolder>() {

    class MovieViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var tvName: TextView = itemView.findViewById(R.id.tvName)
    }
}


There are two problems with the adapter that require our immediate attention.

First problem.  R.layout.recycler_item doesn’t exist. Let’s create it. In the Project View, open res and right click on layout and select Layout resource file.

Image title

Name it  recycler_item. It will be a simple view consisting of one TextView within a LinearLayout. This TextView will be responsible for displaying the title of a movie.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:padding="16dp">

    <TextView
            android:id="@+id/tvName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Test"
            android:textSize="22sp"
    />

</LinearLayout>


That’s the first problem solved. Check.

Onto the second problem. The class MovieRecyclerAdapter does not implement an abstract base class member. This means that we must implement a few methods before our adapter is ready.

The method number one is onCreateViewHolder(), which inflates a view (hint: this will be our newly created view).

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MovieViewHolder {
    val v = LayoutInflater.from(parent.context).inflate(R.layout.recycler_item, parent, false)

    return MovieViewHolder(v)
}


The method number two is getItemCount(),which, as you can guess, tells the adapter the number of items it is to display. This method will simply return the size of the list passed to the adapter.

override fun getItemCount(): Int {
    return myDataset.size
}


And the third and final method is onBindViewHolder(), which is responsible for updating the inflated view with relevant movie titles.

override fun onBindViewHolder(holder: MovieViewHolder, position: Int) {
    holder.tvName.text = myDataset[position].name
}


If we wanted to display more widgets in therecycler_item, we could easily do so and wire them up like we did the tvName TextView. Simple.

With both of the issues solved, our adapter is ready to be used. Go back to theMovieListFragment and assign this adapter to the recycler view. You can add it to many places in this class; for convenience and simplicity, I’m instantiating it inside the observer.

mViewModel.retrieveMovies().observe(this,  Observer {

    Timber.i("received the movies ${it.size}")

    rvList.adapter = MovieRecyclerAdapter(it)

})


Run the app, and now, you can add and preview items stored in the database! Hooray! It took a while to get to this point, but you’ve learned many invaluable lessons along the way, or so I hope.

Image title

Conclusion

We have finally reached a point where we can actually see the results of persisting the data in Room. The contents of this tutorial so far overlap with some basic functionality of the majority of apps, and you can easily apply this knowledge to whatever your app idea is. Instead of persisting Movies, you can store Todos, ShoppingItems, or anything you dream of. This tutorial concludes the Introduction to Android App Development with Kotlin tutorial series — unless enough people request certain features to be implemented on top of this basic app.

The complete working code can be found in this GitHub repo where each lesson is tagged appropriately.

Topics:
kotlin 1.3 ,android app developement ,adapter ,recyclerview ,recycle adapter ,kotlin ,kotlin for android ,java ,tutorial

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}