/** * Sets the checked state of the specified position. The is only valid if the choice mode has been * set to {@link ChoiceMode#SINGLE} or {@link ChoiceMode#MULTIPLE}. * * @param position The item whose checked state is to be checked * @param checked The new checked state for the item */ public void setItemChecked(int position, boolean checked) { if (mChoiceMode == ChoiceMode.NONE) { return; } final Adapter adapter = mRecyclerView.getAdapter(); if (mChoiceMode == ChoiceMode.MULTIPLE) { boolean oldValue = mCheckedStates.get(position); mCheckedStates.put(position, checked); if (mCheckedIdStates != null && adapter.hasStableIds()) { if (checked) { mCheckedIdStates.put(adapter.getItemId(position), position); } else { mCheckedIdStates.delete(adapter.getItemId(position)); } } if (oldValue != checked) { if (checked) { mCheckedCount++; } else { mCheckedCount--; } } } else { boolean updateIds = mCheckedIdStates != null && adapter.hasStableIds(); // Clear all values if we're checking something, or unchecking the currently // selected item if (checked || isItemChecked(position)) { mCheckedStates.clear(); if (updateIds) { mCheckedIdStates.clear(); } } // This may end up selecting the checked we just cleared but this way // we ensure length of mCheckStates is 1, a fact getCheckedItemPosition relies on if (checked) { mCheckedStates.put(position, true); if (updateIds) { mCheckedIdStates.put(adapter.getItemId(position), position); } mCheckedCount = 1; } else if (mCheckedStates.size() == 0 || !mCheckedStates.valueAt(0)) { mCheckedCount = 0; } } updateOnScreenCheckedViews(); }
@Override boolean performItemClick(RecyclerView parent, View view, int position, long id) { final Adapter adapter = mRecyclerView.getAdapter(); boolean checkedStateChanged = false; if (mChoiceMode == ChoiceMode.MULTIPLE) { boolean checked = !mCheckedStates.get(position, false); mCheckedStates.put(position, checked); if (mCheckedIdStates != null && adapter.hasStableIds()) { if (checked) { mCheckedIdStates.put(adapter.getItemId(position), position); } else { mCheckedIdStates.delete(adapter.getItemId(position)); } } if (checked) { mCheckedCount++; } else { mCheckedCount--; } checkedStateChanged = true; } else if (mChoiceMode == ChoiceMode.SINGLE) { boolean checked = !mCheckedStates.get(position, false); if (checked) { mCheckedStates.clear(); mCheckedStates.put(position, true); if (mCheckedIdStates != null && adapter.hasStableIds()) { mCheckedIdStates.clear(); mCheckedIdStates.put(adapter.getItemId(position), position); } mCheckedCount = 1; } else if (mCheckedStates.size() == 0 || !mCheckedStates.valueAt(0)) { mCheckedCount = 0; } checkedStateChanged = true; } if (checkedStateChanged) { updateOnScreenCheckedViews(); } return false; }
public void onAdapterDataChanged() { final Adapter adapter = mRecyclerView.getAdapter(); if (mChoiceMode == ChoiceMode.NONE || adapter == null || !adapter.hasStableIds()) { return; } final int itemCount = adapter.getItemCount(); // Clear out the positional check states, we'll rebuild it below from IDs. mCheckedStates.clear(); for (int checkedIndex = 0; checkedIndex < mCheckedIdStates.size(); checkedIndex++) { final long currentId = mCheckedIdStates.keyAt(checkedIndex); final int currentPosition = mCheckedIdStates.valueAt(checkedIndex); final long newPositionId = adapter.getItemId(currentPosition); if (currentId != newPositionId) { // Look around to see if the ID is nearby. If not, uncheck it. final int start = Math.max(0, currentPosition - CHECK_POSITION_SEARCH_DISTANCE); final int end = Math.min(currentPosition + CHECK_POSITION_SEARCH_DISTANCE, itemCount); boolean found = false; for (int searchPos = start; searchPos < end; searchPos++) { final long searchId = adapter.getItemId(searchPos); if (currentId == searchId) { found = true; mCheckedStates.put(searchPos, true); mCheckedIdStates.setValueAt(checkedIndex, searchPos); break; } } if (!found) { mCheckedIdStates.delete(currentId); mCheckedCount--; checkedIndex--; } } else { mCheckedStates.put(currentPosition, true); } } }