RecyclerView Selection Library Tutorial for Android: Adding New Actions

Learn how to implement press and long-press events on lists with RecyclerView Selection library. By Carlos Mota.

5 (1) · 1 Review

Download materials
Save for later
Share

Android RecyclerViews are among the most used components throughout Android apps. They also are among the most powerful ones, optimized to display large sets of information on which users can easily browse.

Due to its popularity, a set of libraries allows you to empower RecyclerViews even more and give them additional functionalities. One of those is the selection library, which allows easy implementation of press and long-press events on lists.

In this tutorial, you’ll build a grocery list app. It uses the selection library to provide extra features the user can interact with, namely:

  • Pressing an item crosses it from the list.
  • Long-pressing an item triggers multiple-selection mode.
Note: This tutorial assumes you’re familiar with Android Studio and the basics of Android development. If you’re new to either, read Beginning Android Development and Kotlin for Android: An Introduction before continuing.

Getting Started

Download the starter project by clicking the Download Materials button at the top or bottom of the tutorial.

You’ll find two projects inside the ZIP file. Starter has the skeleton of the app you’ll build, and Final gives you something to compare your code against when you’re done.

Build and run the app. You’ll see an app that consists of a shopping list prefilled with groceries:

Bring Cookies feature set: Add a new item, mark items as done and remove items

You’re going to create BringCookies, an app that helps you keep track of everything you need to buy. It comes with a bonus feature! The item Cookies is always on the list because there’s always room for more cookies. :]

Understanding the Project Structure

Open the Starter project in Android Studio and wait for it to synchronize.

The directory structure of the project

You’ll see a set of packages and other important files:

  • adapters: This contains the RecyclerView adapter and a set of utilities used to select items from the list.
  • model: It contains the Item data object used to represent an item. Item consists of id, its value, the timestamp of when it was created and done, the current state.
  • MainActivity: The app’s single activity.
  • MainFragment: It’s responsible for displaying the grocery list to the user and providing a set of mechanisms with which the user can interact.
  • Utils: This file contains a set of utility methods you’ll use throughout the project.
Note: In this tutorial, you’ll use RecyclerView to display your grocery list. To learn more advanced content about how to use this view, check out Android RecyclerView Tutorial with Kotlin or Intermediate RecyclerView Tutorial with Kotlin.

Moving on, it’s time to learn more about the selection library.

Implementing Contextual Action Mode

The contextual mode adds a set of functionalities you can apply to selected items. It lives in the app bar. To display the contextual action mode, the user needs to long-press an item.

The app you’re going to develop allows you to remove groceries from your list.

Open the MainFragment.kt file. In the class declaration, you can see you’re already implementing the ActionMode.Callback, which you use to enable/disable this feature.

Note: There’s also an actionMode declared that you use to check the current state of the action mode.

Here are the methods from this callback:

  • onCreateActionMode loads the correct resource file for the action mode menu.
  • onPrepareActionMode, set as true, ensures all the menu actions will update on every launch.
  • onActionItemClicked defines the actions on the items defined in the menu. In this case, there’s only one action defined — delete. When selected, all these items disappear from the current list, which is then saved locally.
  • onDestroyActionMode triggers when the user exits action mode. You can add new items again, and action mode disappears along with all the selected items.

Getting to Know RecyclerView Selection

To make it easier to interact with the items of RecyclerView, the Android team created the selection library. The starter project contains the logic necessary to implement the setOnClickListener and setOnLongClickListener events on a list.

Note: You’ll find the official documentation from the selection library here.

If you open MainAdapter.kt, you see it implements an interface, IAction, with two different methods:

  • onItemUpdate that’s going to be triggered every time the user clicks a checkbox, which marks an item as done.
  • onItemAction enables multi-selection and select items when this mode is on. When the user long-presses an item in the list, this feature gets activated. This feature de-activates when the user clicks either Back or Delete in the action bar.

For now, you need to do all these manually. If you open MainFragment.kt and look for the implementation of these two methods, you see:

  • onItemUpdate: When triggered, the current item state updates to done or not done, and this new value gets stored locally.
  • onItemAction: Depending on the current value of actionMode, it can be enabled via the invocation of startSupportActionMode: If no items are selected, it will be disabled by calling finish. While it’s on, every item click will update its title that corresponds to the number of items selected.

Adding Selection to Your Existing RecyclerView

To access the functionalities from RecyclerView selection, you need to first add the library to the build.gradle file inside the app folder:

implementation 'androidx.recyclerview:recyclerview-selection:1.1.0'

Once you’ve added that, click Synchronize. Android Studio will download all the necessary resources so you can start implementing these new features!

Implementing ItemKeyProvider

With the library added to the project, it’s time to implement the ItemKeyProvider. This class holds the ID’s of the different cells you can select.

ItemKeyProvider currently supports: Parcelable, String and Long objects. You’re going to use the last one in this project.

Navigate to the adapters package, create the ItemsKeyProvider.kt file and add:

//1
class ItemsKeyProvider(private val adapter: MainAdapter) : ItemKeyProvider<Long>(SCOPE_CACHED) {

 //2
 override fun getKey(position: Int): Long =
     adapter.items[position].id

 //3
 override fun getPosition(key: Long): Int =
     adapter.items.indexOfFirst { it.id == key }
}

You’ll need to import: androidx.recyclerview.selection.ItemKeyProvider.

Here’s a step-by-step breakdown of this logic:

You can use two scope types to initialize this class:

  1. The ItemsKeyProvider receives the adapter where it’s going to be used. You’ll use the parameter id from Item, which is defined as Long, so you’ll need to set and extend this type via ItemKeyProvider.

    You can use two scope types to initialize this class:

    • SCOPE_MAPPED allows access to all the data in the adapter. Typically, this is used when the user wants to select all items in a list with a single click instead of marking them individually.
    • SCOPED_CACHED provides access only to items that were recently bound. This fits into the scenario of a multi-selection option, similar to the grocery list you’re developing, and is the one you’re going to use.
  2. Returns the key of the selection element at a specific position.
  3. From a specific key, it returns its position in the list.

ItemKeyProvider declares both getKey and getPosition methods, which you need to define on this newly created class. This is required because the logic of retrieving the key, and its index, depend on the implementation of which parameter the developer decides to use as key.