Step-by-step Guides to Implement RecycleView
Tags: android, beginners, programming, kotlin
Published: 2022-03-12 01:51:02

**Simple RecycleView demo to create dynamic lists to efficiently display large sets of data for your Android app**

This is the Android `RecycleView` adapter architecture class diagram. I draw this because it helps me to understand the overall picture.

![Android_RecycleView_Adapter_Class_Diagram.drawio.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1642062696632/ISJY-woiX.png)

### 1. Implement and create `ViewModel` to hold RecycleView `ItemData`

This is just an example of recycle view `ItemData`. For simplicity, it just holds one data, which is the `id`.

```kotlin
data class ItemData (val id : Int)
```
`mockItems()` is used to create a fake data. In practice, the data could be coming from repository either through remote and local data source.

```kotlin
class MainViewModel : ViewModel() {
    private val _items = MutableLiveData<List<ItemData>>()
    val items: LiveData<List<ItemData>>
        get() = _items

    init {
        mockItems()
    }

    private fun mockItems() {
        val itemDataList = mutableListOf<ItemData>()

        for(count in 1..100) {
            val data = ItemData(id = count)
            itemDataList.add(data)
        }
        _items.postValue(itemDataList)
    }
}
```

In `MainFragment`, create the `ViewModel`. See my previous post - [Recommended Ways To Create ViewModel](https://vtsen.hashnode.dev/recommended-ways-to-create-viewmodel-or-androidviewmodel)
```kotlin
private val viewModel: MainViewModel by viewModels()
```
### 2. Implement RecycleView `item.xml` layout
`item.xml` represents a single element in the `RecycleView`.

Before updating the layout, you need to enable the [data binding](https://vtsen.hashnode.dev/view-binding-vs-data-binding-gotchas) in your app `build.gradle`.

```
buildFeatures {  
    dataBinding true  
}
```

Add data variable into the `item.xml`, add `TextView` and assign the `itemData.Id` to the `android:text` attribute.
```xml
<?xml version="1.0" encoding="utf-8"?>  
<layout 
    xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:app="http://schemas.android.com/apk/res-auto"  
    xmlns:tools="http://schemas.android.com/tools">  
  
    <data>  
        <variable 
            name="itemData"  
            type="com.example.android.recycleviewdemo.ui.main.ItemData" />  
    </data>  
  
    <androidx.constraintlayout.widget.ConstraintLayout  
         android:layout_width="match_parent"  
         android:layout_height="wrap_content">  
  
        <TextView  android:id="@+id/itemId"  
             android:layout_width="wrap_content"  
             android:layout_height="wrap_content"  
             android:text="@{Integer.toString(itemData.id)}" 
             android:textAppearance="@style/TextAppearance.AppCompat.Large"  
             android:textSize="34sp"  
             android:textStyle="bold"  
             app:layout_constraintBottom_toBottomOf="parent"  
             app:layout_constraintEnd_toEndOf="parent"  
             app:layout_constraintStart_toStartOf="parent"  
             app:layout_constraintTop_toTopOf="parent"  
             tools:text="1" />  
    </androidx.constraintlayout.widget.ConstraintLayout>  
</layout>
```

### 3. Add `RecycleView` into `MainFragment` layout

Add `viewModel` data variable, add `RecycleView` (uses `LinearLayoutManager`). 

```xml
<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="viewModel"
            type="com.example.android.recycleviewdemo.ui.main.MainViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".ui.main.MainFragment">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
            tools:listitem="@layout/item"/>

        </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
```

### 4. Implement`ItemViewHolder` that extends `RecycleView.ViewHolder`

Implement the `bindData()` function bind the `itemData` into `item` layout view.

```kotlin
class ItemViewHolder(
    private val binding: ItemBinding
) : RecyclerView.ViewHolder(binding.root) {

    private lateinit var _itemData: ItemData

    fun bindData(itemData: ItemData) {
        _itemData = itemData
        binding.itemData = _itemData
        binding.executePendingBindings()
    }
}
```

### 5. Implement `ItemDiffCallback` singleton object

This is required in the next step to create the `RecycleViewAdapter`
```kotlin
object ItemDiffCallback : DiffUtil.ItemCallback<ItemData>() {
    override fun areItemsTheSame(oldItem: ItemData, newItem: ItemData): Boolean {
        return oldItem.id == newItem.id
    }

    override fun areContentsTheSame(oldItem: ItemData, newItem: ItemData): Boolean {
        return (oldItem == newItem)
    }
}
```

### 6. Implement `RecycleViewAdapter` that extends `ListAdapter`

Extents `ListAdapter<ItemData, ItemViewHolder>` and passing in the `ItemDiffCallback`, implement `onCreateViewHolder()` and `onBindViewHolder()` functions.

```kotlin
class RecycleViewAdapter()
    : ListAdapter<ItemData, ItemViewHolder> (ItemDiffCallback) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {

        val itemBinding = ItemBinding.inflate(
            LayoutInflater.from(parent.context),
            parent, false)

        return ItemViewHolder(itemBinding)
    }

    override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
        holder.bindData(getItem(position))
    }
}
```

### 7. Create `RecycleViewAdapter` and assign it to `RecycleView` in `onCreateView()` fragment
You also need to observe the `viewModel.item` live data and call `ListAdapter.submitList()`

```kotlin
override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View {

    val binding = MainFragmentBinding.inflate(inflater)

    val adapter = RecycleViewAdapter()
    binding.recyclerView.adapter = adapter

    viewModel.items.observe(viewLifecycleOwner, { items ->
        adapter.submitList(items)
    })

    return binding.root
}
```

That's it! It is done!

![Android_RecycleView_Adapter_Class_Diagram_01.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1639969244865/rexnAjS8u.gif)

### References
- Source code used in this example: [Simple RecycleView Demo](https://github.com/vinchamp77/Demo_SimpleRecycleView)
- For more sophisticated `RecycleView` example, you can refer to my [Malaysian Sydney Food App](https://github.com/vinchamp77/MalaysianSydneyFood).

---

### See Also
- [Convert RecycleView to LazyColumn - Jetpack Compose](https://vtsen.hashnode.dev/convert-recycleview-to-lazycolumn-jetpack-compose)

*Originally published at [https://vtsen.hashnode.dev](https://vtsen.hashnode.dev/step-by-step-guides-to-implement-recycleview)*.