How-To: Handle Selection

This how-to guide will show you how to work with the selection of items, both by user gesture and programmatically. If you would like to configure the styling options for selected items then take a look at our How-To: Style the Grid guide. For a more in-depth look at item selection within the ShinobiGridView head over to the Control Overview: Selection section.

In order to create a grid where items can be selected you need to do the following:

  1. Add a number of columns to the grid with appropriate ColumnSpecs to provide some data.
  2. Specify the item selection mode (if you don’t want the default multi-select behavior).

For the purposes of this how-to guide it is assumed that you already know how to render basic tabular data within the ShinobiGridView, if not, it is suggested that you follow the Quick Start Guide.

Applying Selection Programmatically

It is possible to select items within the ShinobiGridView using the selection API. This may be particularly useful if you wish to have items selected in response to some other action on your application, such as a button being pressed. Setting the selection status of items is really very simple:

Java

shinobiGridView.getDataRecyclerView().setItemSelected(position, selectionState);

C#

shinobiGridView.DataRecyclerView.SetItemSelected(position, selectionState);

The position parameter is the position of the item within the grid. You can use the getPosition(columnIndex, rowIndex) method on either the header or main body GridRecyclerView to find the position of an item at a specific row and column. Conversely you can find the column or row index for a particular position by using the getColumnIndexForPosition and getRowIndexForPosition methods. The selectionState parameter is a boolean which must be set to true for a status of selected or false for deselected.

Additionally, you can query the GridRecyclerView to find out if the item at a specific position is selected, by using the isItemSelected(position) method, and what the positions of all the currently selected items are, by using the getSelectedItemPositions() method.

Selection Modes

The ShinobiGridView has the concept of a selection mode. This defines how the selection of an item is handled when the setItemSelected method is called on the ShinobiGridView. Consequently we have a SelectionMode interface to represent this.

We provide two convenience implementations - MultiSelectionMode and SingleSelectionMode. MultiSelectionMode, which is enabled by default, will allow selection of multiple items without restriction. SingleSelectionMode on the other hand will only allow one item at a time to be selected. An item which is selected will be deselected upon the selection of a different item. Setting the selection mode requires one line of code:

Java

shinobiGridView.setItemSelectionMode(new SingleSelectionMode());

C#

shinobiGridView.ItemSelectionMode = new SingleSelectionMode();

For advanced selection behavior you are free to create your own SelectionMode and this is exactly what we will do in this How-to Guide; let’s create a custom SelectionMode that selects a whole row instead of individual items.

In the sample app we have created a static nested class called RowSelectionMode which implements the SelectionMode interface (or ISelectionMode for Xamarin). The only method in this interface is the setSelected method:

Java

@Override
public void setSelected(int itemPosition, boolean selected, Selector selector) {
}

C#

public void SetSelected(int itemPosition, Boolean selected, Selector selector)
{
}

In this method we are given the position of the item that has been requested to be selected/deselected, the requested selection state for this item (true to select, false to deselect) and a Selector which assists in doing the actual selection and deselection of items as well as informing us of what items are currently selected.

In order to implement row selection we first need to work out the rowIndex of the item that has been requested to be selected/deselected. We can use the Selector to help with this (it has similar position to row and column index conversion methods as the GridRecyclerView):

Java

@Override
public void setSelected(int itemPosition, boolean selected, Selector selector) {

    int itemRowIndex = selector.getRowIndexForPosition(itemPosition);
}

C#

public void SetSelected(int itemPosition, Boolean selected, Selector selector)
{
    int itemRowIndex = selector.GetRowIndexForPosition(itemPosition);
}

With that determined we can now select or deselect all the items in the row based on the chosen selection state:

Java

@Override
public void setSelected(int itemPosition, boolean selected, Selector selector) {

    int itemRowIndex = selector.getRowIndexForPosition(itemPosition);

    if (selected) {
        selector.select(selector.getPosition(0, itemRowIndex));
        selector.select(selector.getPosition(1, itemRowIndex));
    } else {
        selector.deselect(selector.getPosition(0, itemRowIndex));
        selector.deselect(selector.getPosition(1, itemRowIndex));
    }
}

C#

public void SetSelected(int itemPosition, Boolean selected, Selector selector)
{
    int itemRowIndex = selector.GetRowIndexForPosition(itemPosition);

    if (selected)
    {
        selector.Select(selector.GetPosition(0, itemRowIndex));
        selector.Select(selector.GetPosition(1, itemRowIndex));
    }
    else
    {
        selector.Deselect(selector.GetPosition(0, itemRowIndex));
        selector.Deselect(selector.GetPosition(1, itemRowIndex));
    }
}

Finally, we set an instance of this RowSelectionMode on the ShinobiGridView:

Java

shinobiGridView.setItemSelectionMode(new RowSelectionMode());

C#

shinobiGridView.ItemSelectionMode = new RowSelectionMode();

Applying Selection by Gesture

To respond to user gestures the ShinobiGridView needs to be told to ‘listen’ for gesture events, and then react appropriately. As some may be aware the RecyclerView class, which the ShinobiGridView’s GridRecyclerViews extend, has an OnItemTouchListener interface to assist with gesture detection.

The shinobigrids library offers a convenience implementation of this interface for detecting single taps - the ItemSingleTapDetector class. An instance of this class is added to the GridRecyclerView that represents the main body of data in the grid by default. To add behavior that will be invoked upon a single tap of an item, you simply need to implement the ItemSingleTapDetector’s Callback interface (ICallback for Xamarin). This interface is very simple with just the one method - onItemSingleTap. When this method is invoked the position of the item which was tapped is provided along with the ViewHolder for the item.

The default ItemSingleTapDetector is automatically given a Callback that uses the selection API described above to toggle the selection state of the tapped item. Its implementation looks similar to the following:

Java

@Override
public void onItemSingleTap(RecyclerView.ViewHolder holder, int position) {
    GridRecyclerView dataRecyclerView = shinobiGridView.getDataRecyclerView();
    dataRecyclerView.setItemSelected(position, !dataRecyclerView.isItemSelected(position));
}

C#

public void OnItemSingleTap(RecyclerView.ViewHolder holder, int position)
{
    GridRecyclerView dataRecyclerView = shinobiGridView.DataRecyclerView;
    dataRecyclerView.SetItemSelected(position, !dataRecyclerView.IsItemSelected(position));
}

So as you can see, out-of-the-box the ShinobiGridView allows you to select and deselect its items by single tap gestures. If you run the code sample, and make selections by tapping various items, you will see our custom RowSelectionMode in action; tapping an item selects/deselects both items in the same row.

Selection

Of course you can create your own OnItemTouchListener to respond to different gestures, such as long presses or double taps. Through the ShinobiGridView and GridRecyclerView APIs these listeners can be added and removed. For further information see the Control Overview: Gestures section.

See the related code sample: Selection in the samples/selection folder of your product download.