In this post, we’ll be looking at the Contextual Action Bar (CAB). CABs are a great way to let your users select multiple items and then take action on all of those items at once. One place you’ve probably seen a CAB is when deleting items from a RecyclerView, which is exactly what we’ll be doing here! If you’re still not sure what a CAB is here’s a glimpse of the app we’ll be creating:
To make things a bit easier we’re going to start with an already built app which can be found here; it’s just a simple RecyclerView containing the numbers 0 to 19.
Ok, back to the CAB. Let’s start by trying to launch the CAB when we long-press on an item. To launch it we just need to call ‘startSupportActionMode’ on an AppCompatActivity (or ‘startActionMode’ on an Activity) and pass in an instance of ActionMode.Callback.
So inside the ‘update’ function of the ViewHolder let’s add an OnLongClickListener and start the ActionMode:
Next, we need to fill in that ‘actionModeCallbacks’ object. But before we get to that let’s create a couple new fields to help us keep track of our app’s state. Specifically, we need to know if the user should be able to select items and also which items are selected:
private boolean multiSelect = false; private ArrayList<Integer> selectedItems = new ArrayList<Integer>();
Getting back to our callbacks, let’s create a new anonymous ActionMode.Callback object on the next line and implement the required methods:
The first method is ‘onCreateActionMode’. This method is called once when the ActionMode is first created and is where we should set up the Menu. To keep things simple, I’m just going to add one MenuItem that says ‘Delete’ and then return true to signify that Android should continue creating the Menu. Also, since this is called when we’re first entering the ActionMode, it’s a good place to set our ‘multiSelect’ variable:
At this point, we can long-press on an item and see our CAB! But it doesn’t do anything yet; it just shows our Delete option.
Moving onto ‘onPrepareActionMode’, this method will be called anytime the CAB is invalidated. So if you want to update your CAB while it’s being displayed, this would be the place to do it, and you’d want to return true to tell Android that you’ve updated the CAB. In this app we don’t have any reason to update the CAB, so we can just leave this as is.
Next up is the ‘onActionItemClicked’ method. As you probably guessed, this method is called whenever one of your CAB’s MenuItems is clicked. Normally you’d need to add some handling to determine which MenuItem was clicked, but since this app only has one MenuItem all we need to do is delete the selected items and then call ‘mode.finish()’, which tells Android that we’re done with the CAB and results in a call to ‘onDestroyActionMode’. We should also return true to say that we handled the event:
Last but not least is ‘onDestroyActionMode’. This method is called whenever the user leaves the CAB or you call ‘finish()’ on the ActionMode. After this point the CAB will no longer be displayed, so this is a good spot to set ‘multiSelect’ to false as well as clear out our ‘selectedItems’ list. It’s also a good place to call ‘notifyDataSetChanged()’ to make sure that we’re keeping our adapter up to date with our ‘items’ List:
Perfect! Now that we’ve finished up our ActionMode.Callback object, all that’s left is adding the ability to add items to our ‘selectedItems’ array and updating the UI to show whether or not an item is selected.
Let’s start by creating a new function named ‘selectItem’. This function will take in an item, and if the user is in ‘multiSelect’ mode, then we’ll update the ‘selectedItems’ list and change the background color:
Next, we just need to add an OnClickListener to our ‘itemView’, and call ‘selectItem’ when the item is clicked. We should also call ‘selectItem’ before the return in our OnLongClickListener; this way when a user long-clicks on an item it’ll start selected:
Now that we’re updating our List and the UI, we should be good to go, right? Let’s find out, here’s what it looks like when I run the app:
When those items get deleted we’re doing a great job of removing them from the List and updating the adapter, but we’re not doing such a good job of updating the ViewHolders they used to inhabit. To fix this we just need to add some code to our update function to update the background as well as the text:
And with that, we’ve now got a fully functional Contextual Action Bar that lets us delete items from a RecyclerView! If you like to check out the code for this app, here’s a link to the GitHub project.
Also, if you’re looking to learn more about Android development, then I suggest you start here. We’ll take you from novice to Android developer one step at a time and explain everything along the way. On the other hand, if you’re looking for something a bit more advanced then I strongly encourage you to check out our Kotlin course. It covers everything you need to know about Kotlin, and it does so by building a Solitaire app. I had a lot of fun making it, and I think you’ll like it!
Comments are closed.