Step-by-step Guides to Implement RecycleView

vtsen

Vincent Tsen

Posted on March 12, 2022

Step-by-step Guides to Implement RecycleView

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

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.

data class ItemData (val id : Int)
Enter fullscreen mode Exit fullscreen mode

mockItems() is used to create a fake data. In practice, the data could be coming from repository either through remote and local data source.

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)
    }
}
Enter fullscreen mode Exit fullscreen mode

In MainFragment, create the ViewModel. See my previous post - Recommended Ways To Create ViewModel

private val viewModel: MainViewModel by viewModels()
Enter fullscreen mode Exit fullscreen mode

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 in your app build.gradle.

buildFeatures {  
    dataBinding true  
}
Enter fullscreen mode Exit fullscreen mode

Add data variable into the item.xml, add TextView and assign the itemData.Id to the android:text attribute.

<?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>
Enter fullscreen mode Exit fullscreen mode

3. Add RecycleView into MainFragment layout

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

<?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>
Enter fullscreen mode Exit fullscreen mode

4. ImplementItemViewHolder that extends RecycleView.ViewHolder

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

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()
    }
}
Enter fullscreen mode Exit fullscreen mode

5. Implement ItemDiffCallback singleton object

This is required in the next step to create the RecycleViewAdapter

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)
    }
}
Enter fullscreen mode Exit fullscreen mode

6. Implement RecycleViewAdapter that extends ListAdapter

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

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))
    }
}
Enter fullscreen mode Exit fullscreen mode

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()

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
}
Enter fullscreen mode Exit fullscreen mode

That's it! It is done!

Android_RecycleView_Adapter_Class_Diagram_01.gif

References


See Also

Originally published at https://vtsen.hashnode.dev.

💖 💪 🙅 🚩
vtsen
Vincent Tsen

Posted on March 12, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related