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.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
RecyclerView Selection Library Tutorial for Android: Adding New Actions
20 mins
- Getting Started
- Understanding the Project Structure
- Implementing Contextual Action Mode
- Getting to Know RecyclerView Selection
- Adding Selection to Your Existing RecyclerView
- Implementing ItemKeyProvider
- Implementing ItemDetailsLookup
- Updating MainAdapter
- Implementing a SelectionTracker
- Updating MainAdapter Initialization
- Updating ActionMode Callbacks
- Saving and Restoring State
- Where to Go From Here?
Updating MainAdapter Initialization
Now that you defined tracker
, you need to update the call to MainAdapter, which is no longer the IAction interface. Instead, it’s a lambda function containing the code from onItemUpdate
.
Still in setupUiComponents
, scroll up to the method declaration and replace the mainAdapter
definition with:
val mainAdapter = MainAdapter { items: List<Item>, changed: Item, checked: Boolean ->
var element = items.first { it.id == changed.id }
val index = items.indexOf(element)
element = if (index == 0) {
Snackbar.make(binding.clContainer, R.string.item_more_cookies, Snackbar.LENGTH_SHORT).show()
element.copy(done = false)
} else {
element.copy(done = checked)
}
val updatedItems = items.toMutableList().apply { this[index] = element }
updateAndSave(updatedItems)
}
Like the onSelectionChanged
callback, the MainAdapter initialization corresponds to the code from onItemUpdate
. Every time an item state changes in the groceries list, this value updates in the local storage.
Updating ActionMode Callbacks
There are a few more things to update before you can recompile the project. Following the errors in red, in the code, you’ll need to update onActionItemClicked
with this newly added logic.
To access the items that are currently selected, you no longer access a variable inside the adapter. Instead, you can now directly call the tracker
you’ve just created.
Update selected
to:
val selected = mainAdapter.items.filter {
tracker.selection.contains(it.id)
}.toMutableList()
Because tracker
holds the ID’s of the currently selected items, you need to filter the existing items list to return only the selected ones.
Moving forward, you also need to update onDestroyActionMode
. Because clearSelection
no longer exists, to remove all the items that are currently selected, you need to call instead:
tracker.clearSelection()
Now that you’re all set, delete the implementation of IAction at the class declaration and its functions. Scroll down to the end of the file and remove the onItemUpdate
and onItemAction
functions.
It’s time to finally build and run the app. Before your next trip to buy groceries, don’t forget to remove the items you no longer need. Long-press in the list, select one or more elements, and click Delete.
Saving and Restoring State
Now that you’ve got your selection library implemented, you can take an extra step to guarantee your items will still be selected across different lifecycle events.
If you select a couple items and then switch your screen to landscape, you see they all disappear. To avoid this, you need to override the onSaveInstanceState
and onViewStateRestored
methods in MainFragment.kt:
override fun onSaveInstanceState(outState: Bundle) {
tracker.onSaveInstanceState(outState)
super.onSaveInstanceState(outState)
}
override fun onViewStateRestored(savedInstanceState: Bundle?) {
tracker.onRestoreInstanceState(savedInstanceState)
if (tracker.hasSelection()) {
actionMode = (activity as MainActivity).startSupportActionMode(this@MainFragment)
actionMode?.title = getString(R.string.action_selected, tracker.selection.size())
}
super.onViewStateRestored(savedInstanceState)
}
In each of these methods, you need to call the corresponding method from tracker
. The selection library will handle the rest automatically.
Build and run the app, select a couple items and rotate the device to landscape.
Where to Go From Here?
Download the completed project files by clicking the Download Materials button at the top or bottom of the tutorial.
Congratulations! You’ve learned how to implement the selection library into your RecyclerView. You’ve added press and long-press events into your app.
This is just a small example of features you can use with RecyclerView. Other tutorials focus on how to speed up its performance for large lists or how to use the Paging library to only load the necessary information on the screen.
If you have any questions or comments, please join the discussion below.