예제 #1
0
 @Override
 public void handleMessage(Message msg) {
   switch (msg.what) {
     case OnItemChecked:
       // 为局部刷新用
       ArrayList<Integer> change = new ArrayList<Integer>();
       int p = (Integer) msg.obj;
       change.add(p);
       if (beans.get(p).isChecked()) {
         beans.get(p).setChecked(false);
       } else {
         int size = getCheckedSize();
         while (size >= 10) {
           for (int i = 0; i < beans.size(); i++) {
             if (beans.get(i).isChecked()) {
               beans.get(i).setChecked(false);
               change.add(i);
               size--;
               break;
             }
           }
         }
         beans.get(p).setChecked(true);
       }
       updateItems(change);
       break;
     default:
       break;
   }
   super.handleMessage(msg);
 }
  /**
   * Defines the choice behavior for the List. By default, Lists do not have any choice behavior
   * ({@link ChoiceMode#NONE}). By setting the choiceMode to {@link ChoiceMode#SINGLE}, the List
   * allows up to one item to be in a chosen state. By setting the choiceMode to {@link
   * ChoiceMode#MULTIPLE}, the list allows any number of items to be chosen.
   *
   * @param choiceMode One of {@link ChoiceMode#NONE}, {@link ChoiceMode#SINGLE}, or {@link
   *     ChoiceMode#MULTIPLE}
   */
  public void setChoiceMode(ChoiceMode choiceMode) {
    if (mChoiceMode == choiceMode) {
      return;
    }

    mChoiceMode = choiceMode;

    if (mChoiceMode != ChoiceMode.NONE) {
      if (mCheckedStates == null) {
        mCheckedStates = new CheckedStates();
      }

      final Adapter adapter = mRecyclerView.getAdapter();
      if (mCheckedIdStates == null && adapter != null && adapter.hasStableIds()) {
        mCheckedIdStates = new CheckedIdStates();
      }
    }
  }
  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);
      }
    }
  }
  /**
   * 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;
    }
 @Override
 public boolean handleKeyboardShortcutRepeat(
     @NonNull final KeyboardShortcutsHandler handler,
     final int keyCode,
     final int repeatCount,
     @NonNull final KeyEvent event,
     int metaState) {
   final String action = handler.getKeyAction(CONTEXT_TAG_NAVIGATION, keyCode, event, metaState);
   if (action == null) return false;
   final int direction;
   switch (action) {
     case ACTION_NAVIGATION_PREVIOUS:
       {
         direction = -1;
         break;
       }
     case ACTION_NAVIGATION_NEXT:
       {
         direction = 1;
         break;
       }
     case ACTION_NAVIGATION_PAGE_DOWN:
       {
         RecyclerViewUtils.pageScroll(view, manager, 1);
         return true;
       }
     case ACTION_NAVIGATION_PAGE_UP:
       {
         RecyclerViewUtils.pageScroll(view, manager, -1);
         return true;
       }
     default:
       {
         return false;
       }
   }
   final View focusedChild =
       RecyclerViewUtils.findRecyclerViewChild(view, manager.getFocusedChild());
   final int position;
   final int firstVisibleItemPosition = manager.findFirstVisibleItemPosition();
   final int lastVisibleItemPosition = manager.findLastVisibleItemPosition();
   final int itemCount = adapter.getItemCount();
   final boolean backupOutsideRange =
       positionBackup > lastVisibleItemPosition || positionBackup < firstVisibleItemPosition;
   if (focusedChild != null) {
     position = view.getChildLayoutPosition(focusedChild);
   } else if (firstVisibleItemPosition == 0) {
     position = -1;
   } else if (lastVisibleItemPosition == itemCount - 1) {
     position = itemCount;
   } else if (direction > 0 && backupOutsideRange) {
     position = firstVisibleItemPosition;
   } else if (direction < 0 && backupOutsideRange) {
     position = lastVisibleItemPosition;
   } else {
     position = positionBackup;
   }
   positionBackup = position;
   RecyclerViewUtils.focusNavigate(view, manager, position, direction);
   return true;
 }