Skip to content

RecyclerView

This codebase provide you with base class for RecyclerViewAdapter and ItemViewHolder.

Preparation

Before using the base class, make sure to define this two components first:

Model Object

data class User(
  val id: Int,
  val name: String,
  val avatar: String,
  val email: String
)

Item Layout

  <?xml version="1.0" encoding="utf-8"?>
  <androidx.constraintlayout.widget.ConstraintLayout
      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" android:layout_width="match_parent"
      android:layout_height="wrap_content" android:background="?attr/selectableItemBackground"
      android:padding="10dp">

      <ImageView android:id="@+id/ivUser" android:layout_width="0dp" android:layout_height="76dp"
          app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintDimensionRatio="1:1"
          app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"
          tools:ignore="ContentDescription" tools:srcCompat="@tools:sample/avatars" />

      <TextView android:id="@+id/tvUserName" android:layout_width="0dp"
          android:layout_height="wrap_content" android:layout_marginStart="10dp"
          android:textAppearance="@style/TextAppearance.AppCompat.Medium"
          android:textColor="@android:color/white" android:textStyle="bold"
          app:layout_constraintStart_toEndOf="@id/ivUser"
          app:layout_constraintTop_toTopOf="@id/ivUser" tools:text="@tools:sample/full_names" />

      <TextView android:id="@+id/tvUserEmail" android:layout_width="0dp"
          android:layout_height="wrap_content" android:layout_marginStart="10dp"
          android:textAppearance="@style/TextAppearance.AppCompat.Small" android:textStyle="italic"
          app:layout_constraintStart_toEndOf="@id/ivUser"
          app:layout_constraintTop_toBottomOf="@id/tvUserName" tools:text="@tools:sample/cities" />

  </androidx.constraintlayout.widget.ConstraintLayout>

Creating ViewHolder

Here example of creating ItemViewHolder based on two components earlier:

inner class UserHolder(private val itemView: ItemUserBinding) : DevItemViewHolder<User>(itemView) {
        override fun bind(data: User?) {
            with(itemView) {
                data?.let { user ->
                    binding.ivUser.loadImage(
                        c = context,
                        imageUrl = user.avatar,
                        placeHolderResourceId = R.drawable.ic_guest,
                        errorDrawable = getDrawableResource(R.drawable.ic_guest)
                    )

                    binding.tvUserName.text = user.name
                    binding.tvUserEmail.text = user.email
                }
            }
        }
    }

Creating Adapter

Here is example of RecyclerViewAdapter based on two components earlier with ItemViewHolder above:

UserAdapter.kt
class UserAdapter(
    // Here you must define onClickListener, which is a method take the model object as parameter
    onclickListener: ((data: User?) -> Unit),

    // Here you can define onLongClickListener, which is a method take the model object as parameter, nullable if not needed
    onLongClickListener: ((data: User?) -> Unit)? = null

) : DevRecyclerViewAdapter<User, DevItemViewHolder<User>>(onclickListener, onLongClickListener) {

    // Here you must define your ViewHolder, you can add other ViewHolder based on your viewType by adding condition
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DevItemViewHolder<User> =
        UserHolder(ItemUserBinding.inflate(getLayoutInflater(parent)))
}

Customize viewType based on condition in RecyclerView. If the adapter contains more than one ItemViewHolder, define the condition:

override fun getItemViewType(position: Int) = if(condition) viewTypeA else viewTypeB

Endless Scrolling

All Adapter created using DevRecyclerViewAdapter are embedded with endless scrolling. For example, see sample module.


Extension Function

Or if you're being lazy, use this extension function from the RecyclerView:

val adapter = binding.rvUsers.setupWith<ModelData> { // (1)
    // Required
    withLayoutManager(LinearLayoutManager(binding.rvUserAll.context)) // (2)
    withBinding<ItemUserBinding> { data, userBinding ->
        // (3) 
    }

    // Optional
    withClick { data ->
        // (4)
    }

    withLongClick { data ->
        // (5)
    }

    withPagination(paginationListener) // (6)
}

adapter.add(newData) // (7)
  1. This method return the Adapter that configured to the RecyclerView
  2. Define Layout Manager for the RecyclerView
  3. Define the layout and the binding of the model object to the layout
  4. Action when item is clicked
  5. Action when the item is long clicked
  6. Setup pagination
  7. Then, you can use it to call method like adding and removing data

Warning

this feature only supported if viewBinding is enabled