Android recyclerview selection library

Add selection support to RecyclerView Selection

List UI is a very common thing in Android Applications. Pretty much every single app has a list of something they want to display.RecyclerView Selection is a library that will allow you to handle item selection a lot easier. It will help you handle motion events and touch events, and convert them into selection in the RecyclerView.This is a fairly flexible library where it allows creating, modifying, inspecting, and monitoring changes to items in a RecyclerView list. It enables users to select items in RecyclerView list using touch or mouse input.

To add selection support to a RecyclerView instance, follow these steps:

1.Add Dependency

As you can imagine, you add the new dependency to your build.gradle file. An important thing to note here is that we are using the new AndroidX artifact.
Add following dependency to your app’s build.gradle file.28.0.0-alpha is a pre-release version to support the Android P developer preview.

For the setup what you need to do is you want to create a new adapter and important thing is that it uses stable IDs.There is no selection code just yet. You need just basic RecyclerView setup.

2.Implement ItemKeyProvider

Developers must decide on the key type used to identify selected items. There are three key types: Parcelable, String, and Long.ItemKey provider conjunction of stable IDs. It will allow for a quick mapping between the IDs and the items that will handle the selection by the selection library.

3.Implement ItemDetails

ItemDetails implementation provides the selection library with access to information about a specific RecyclerView item. This class is a key component in controling the behaviors of the selection library in the context of a specific activity.

4.Implement ItemDetailsLookup

ItemDetailsLookup enables the selection library to access information about RecyclerView items given a MotionEvent. It is effectively a factory for ItemDetails instances that are backed up by a RecyclerView.ViewHolder instance.

It is actually a fairly simple class. You need to overwrite only one method. That returns the position and the selection key for the item that is for the given motion event.

The Selection library calls getItemDetails() when it needs access to information about the area. Your implementation must negotiate ViewHolder lookup with the corresponding RecyclerView instance and the subsequent conversion of the ViewHolder instance to an ItemDetailsLookup.ItemDetails instance.

The adapter, as I said again, nothing super exciting. The only important thing here is that we’re doing stable IDS. This allows for a consistent mapping from ID to the item.

5.Reflect Selected State

When the user selects an item the library will record that in SelectionTracker then notify RecyclerView that the state of the item has changed.The item must then be updated to reflect the new selection status. Without this, the user will not see that the item has been selected.

Update the styling of the view to represent the activated status with a color state list.

item_list.xml

RecyclerView has no default selection mechanism. You have to handle it in onBind.There you might want to change the background of a view or you can use it by setting activated state to get activates state working. You use background for the view and that background is a selectable drawable that has an activated state which will allow to indicate to the user that the item has been selected.

6.Add Contextual Actions

ActionModes used to provide alternative interaction modes and replace parts of the normal UI until finished. Action modes include text selection and contextual actions.

7.Build SelectionTracker

Now, what we need to set up is the selection tracker, which actually is the actual machinery behind the scenes, and we pass in RecyclerView, the key provider both of these that we just created.
In order to build a SelectionTracker instance, your app must supply the same Adapter that you used to initialize RecyclerView to SelectionTracker.Builder .

Register a SelectionTracker.SelectionObserver to be notified when the selection changes. When a selection is first created, start ActionMode to represent this to the user, and provide selection specific actions.

8.Activity lifecycle events

In order to preserve state you must handling of Activity lifecycle events. your app must call the selection tracker’s onSaveInstanceState() and onRestoreInstanceState() methods from the activity’s onSaveInstanceState()and onRestoreInstanceState() methods respectively.

Источник

Implementing selection in Recyclerview

Whenever you’re dealing with a list of data, it’s likely that you’ll want to give your users options to perform certain actions on multiple items at once. For example, if you have used Google photos or Whatsapp you can select multiple items and delete them, move them to the archive at once instead of performing the delete operation on every image one-by-one.

In this blog, I’ll be outlining how I implemented this same feature using the recyclerview-selection.I’ll be using the new ListAdapter Implementation for RecyclerView but this can be used for the trivial RecyclerView Adapter as well.

Читайте также:  Best audiobook player android

Once done, this is how the app should work:

Let’s first write the code for ListAdapter

The first step is adding the required dependency to our Gradle.build file. Nothing special here.

Next is Selecting the Key Type which is basically is the identity of your element which you have selected. It is important to choose the correct type of key as your further process and action on selected items depend upon it. You can use whichever type you like but the selection library provides support for three types: Parcelable , String and Long .

There are also some guidelines and advice on which type to use depending on your use case.

Parcelable : Any Parcelable type can be used as the selection key. This is especially useful in conjunction with Uri as the Android URI implementation is both parcelable and makes for a natural stable selection key for values represented by the Android Content Provider framework. If items in your view are associated with stable content:// uris, you should use Uri for your key type.

String : Use String when a string based stable identifier is available.

Long : Use Long when RecyclerView’s long stable ids are already in use. It comes with some limitations, however, as access to stable ids at runtime is limited. Band selection support is not available when using the default long key storage implementation.

In this example, we will be using the String type of key as we need string id to remove these items from local DB as well as the server, but first of all, you need to call a function in your adapter which is setHasStableIds .Setting that option to true will just tell the RecyclerView that each item in the data set can be represented with a unique identifier.

We now have to use the position of our items as their ids, to do we can just override the getItemId method and return the position of the item as its id.

Next Step is to implement a KeyProvider which is basically the bridge between our adapter and our item selector.

In the above class, I’ve passed my adapter as an argument because of the string type key, for Long you might not need to implement they class at all. Also, I passed SCOPE_CACHED in the ItemKeyProvider class because i want my selection to persist screen rotation otherwise on-screen rotation selection will be removed. Now the 2 methods which we override gives us the id of selected item and position of selected item respectively.

Now before we move forward let make some changes to our view holder class. We need to define a method that will give us the corresponding string id for our selection. I made my Viewholder class as an inner class so it can access recyclerview getItem method.

Next Step is declaring ItemDetailsLookup, this is the class that will provide the selection library the information about the items associated with the users’ selection.

Now we just need to highlight the selected item and get the list of selected items in our Fragment/Activity. For highlighting the selected item we need a Tracker. A tracker is what’s going to allow the selection library to track the selections of the user, we are going to need it to check if a specific item has been selected or not.

We will also add a new boolean parameter to the bind method in the ViewHolder. That boolean will tell the ViewHolder if the item in that position has been selected by the user or not.

Now I’ll be adding an image view in item_note.xml which is nothing but a tick which will be visible when an item is selected also I’ll be hiding the time of note. Our update bind function would look like this.

Finally, now we just need to create an object of Tracker in our activity and set it to the adapter. To make the object of tracker we are going to need:

  • selectionId: a string to identity our selection in the context of the activity or fragment.
  • recyclerView: the RecyclerView where we will apply the tracker.
  • keyProvider: the source of selection keys.
  • detailsLookup: the source of information about RecyclerView items.
  • storage: strategy for type-safe storage of the selection state.

Here the most important is the SelectionPredicate in which we passed SelectionPredicates.createSelectAnything() that allows us to select multiple items in our list. After this, you’ll be able to select multiple items in your adapter but if you want to get ids of the selected items you’ll be needing an observer as well which will give us the ids as soon as any item selected. It’s pretty straight forward too.

For Enabling selection just by tapping on item rather than long pressing the item

Override the above function in your view holder class inside getItemDetails functions and return true or false for enabling or disabling single tap respectively.

That was everything for today, If you have any questions please leave a comment and if you’re looking for the code you can check out the project below.

Читайте также:  Как сбить до заводских настроек андроид самсунг

Источник

How to Add Multiple Selection to Android RecyclerView

The RecyclerView widget is an integral part of most Android applications today. Ever since it was added to the Android support library in late 2014, it has eclipsed the ListView widget as the most preferred widget for displaying large, complex lists. However, there’s one important feature missing in it: support for selecting and tracking list items. RecyclerView Selection, an addon library Google released in March this year, tries to fix this.

In this tutorial, I’ll show you how to use the new library to create an app that offers an intuitive interface for selecting multiple items in a list. Follow along with this Android RecyclerView multiple selection example, and you’ll learn some skills you can apply in your own apps.

Prerequisites

To follow along, you’ll need:

  • the latest version of Android Studio
  • a device or emulator running Android API level 23 or higher

1. Add RecyclerView Android Dependencies

To add the RecyclerView Selection library to your Android Studio project, mention the following implementation dependencies in your app module’s build.gradle file:

2. Create a List

Throughout this tutorial, we’ll be working with a small list of items, each containing a person’s name and phone number.

To store the data of each list item, create a Kotlin data class called Person and add two properties to it: name and phone .

You can now go ahead and create a list of Person objects in your main activity.

3. Add a Recycler View to the Layout

We will, of course, be using a RecyclerView widget to display the list. So add a tag to your main activity’s layout XML file.

To specify the layout of the list items, create a new XML file and call it list_item.xml. Inside it, add two TextView widgets: one to display the name, and the other to display the phone number. If you use a LinearLayout element to position the widgets, the contents of the XML file should look like this:

4. Create a View Holder

You can think of a view holder as an object that contains references to the views present in the layout of the list items. Without it, the RecyclerView widget will not be able to render the list items efficiently.

For now, you need a view holder that holds the two TextView widgets you created in the previous step. So create a new class that extends the RecyclerView.ViewHolder class, and initialize references to both the widgets inside it. Here’s how:

Additionally, the RecyclerView Selection addon needs a method it can call to uniquely identify selected list items. This method ideally belongs to the view holder itself. Furthermore, it must return an instance of the ItemDetailsLookup.ItemDetails class. Therefore, add the following code to the view holder:

You must now override two abstract methods present in the ItemDetails class. Start by overriding the getPosition() method and returning the adapterPosition property of the view holder inside it. The adapterPosition property is usually nothing but the index of a list item.

Next, override the getSelectionKey() method. This method must return a key that can be used to uniquely identify a list item. To keep things simple, let’s just return the itemId property of the view holder.

You are free to use any other technique for generating the selection key, so long as it generates unique values.

5. Handle User Touches

For the RecyclerView Selection addon to work correctly, whenever the user touches the RecyclerView widget, you must translate the coordinates of the touch into an ItemDetails object.

Create a new class that extends the ItemDetailsLookup class, and add a constructor to it that can accept the RecyclerView widget as an argument. Note that, because the class is abstract, Android Studio will automatically generate a stub for its abstract method.

As you can see in the above code, the getItemDetails() method receives a MotionEvent object. By passing the event’s X and Y coordinates to the findChildViewUnder() method, you can determine the view associated with the list item the user touched. To convert the View object into an ItemDetails object, all you need to do is call the getItemDetails() method. Here’s how:

6. Create an Adapter

You’ll now need an adapter that can bind your list to your RecyclerView widget. To create one, create a new class that extends the RecyclerView.Adapter class. Because the adapter needs access to the list and your activity’s context, the new class must have a constructor that can accept both as arguments.

It is important that you explicitly indicate that each item of this adapter is going to have a unique stable identifier that is of type Long . The best place to do so is inside an init block.

Additionally, to be able to use the position of an item as its unique identifier, you’ll have to override the getItemId() method.

Because the RecyclerView.Adapter class is abstract, you’ll now have to override three more methods to make your adapter usable.

First, override the getItemCount() method to return the size of the list.

Next, override the onCreateViewHolder() method. This method must return an instance of the view holder class you created earlier in this tutorial. To create such an instance, you must call the constructor of the class and pass the inflated layout of your list items to it. To inflate the layout, use the inflate() method of the LayoutInflater class. Here’s how:

Читайте также:  Не включается блокировка экрана андроид

Lastly, override the onBindViewHolder() method and appropriately initialize the text property of both the TextView widgets present in the view holder.

7. Display the List

At this point, you have almost everything you need to render your list. However, you must still specify how you want the list items to be positioned. For now, let’s position them one below the other using a LinearLayoutManager instance.

For optimal performance, I suggest you also indicate that the size of the RecyclerView widget is not going to change during runtime.

Add the following code to your main activity:

Finally, assign a new instance of your adapter to the adapter property of the RecyclerView widget.

If you run your app now, you’ll be able to see the list.

8. Create a Selection Tracker

The RecyclerView widget still doesn’t allow you to select any items. To enable multi-item selection, you’ll need a SelectionTracker object in your activity.

You can initialize the tracker using the SelectionTracker.Builder class. To its constructor, you must pass a selection ID, your RecyclerView widget, a key provider, your item details lookup class, and a storage strategy.

You are free to use any string as a selection ID. As a key provider, you can use an instance of the StableIdKeyProvider class.

The RecyclerView Selection library offers a variety of storage strategies, all of which ensure that selected items are not deselected when the user’s device is rotated or when the Android system closes your app during a resource crunch. For now, because the type of your selection keys is Long , you must use a StorageStrategy object of type Long .

Once the Builder is ready, you can call its withSelectionPredicate() method to specify how many items you want to allow the user to select. In order to support multi-item selection, as an argument to the method, you must pass the SelectionPredicate object returned by the createSelectAnything() method.

Accordingly, add the following code inside your activity’s onCreate() method:

To make the most of the storage strategy, you must always try to restore the state of the tracker inside the onCreate() method.

Similarly, you must make sure you save the state of the tracker inside your activity’s onSaveInstanceState() method.

The selection tracker is not very useful unless it is associated with your adapter. Therefore, pass it to the adapter by calling the setTracker() method.

The setTracker() method doesn’t exist yet, so add the following code inside your adapter class:

If you try running your app at this point, you will be able to select items in the list. When you enter the multi-item selection mode by long-pressing a list item, you’ll be able to feel a brief vibration on most devices. However, because the selected items are currently indistinguishable from the unselected ones, you’ll have no visual feedback. To fix this, you need to make a few changes inside the onBindViewHolder() method of your adapter.

The conventional way to highlight selected items is to change their background color. Therefore, you must now change the background color of the LinearLayout widget that’s present in your items’ layout XML file. To get a reference to it, get a reference to the parent of one of the TextView widgets available in the view holder.

Add the following code just before the end of the onBindViewHolder() method:

Next, you can call the isSelected() method of the SelectionTracker object to determine whether an item is selected or not.

The following code shows you how to change the background color of selected items to cyan:

If you run the app now, you should be able to see the items you select.

9. Create a Selection Observer

Usually, you’d want to show the user how many items are currently selected. With the RecyclerView Selection library, doing so is very easy.

Associate a SelectionObserver object with your selection tracker by calling the addObserver() method. Inside the onSelectionChanged() method of the observer, you can detect changes in the number of items selected.

How you display the number of selected items is up to you. For now, I suggest you display the number directly in the action bar of your activity. Optionally, you can also change the background color of the action bar to let the user know that there is an active selection in the list. The following code shows you how:

If you run the app again, you should now see the title change to reflect the number of list items you select.

Conclusion

In this tutorial, you learned how to use the RecyclerView Selection addon library to add simple item selection support to a RecyclerView widget. You also learned how to dynamically alter the looks of selected items so that users can tell them apart from unselected ones.

To learn more about the library, refer to the official documentation.

Источник

Оцените статью