2015-02-27 2 views
2

Если вы звоните AbsListView.setItemChecked() напрямую, это работает хорошо, и активируется и работает ActionMode.Android: AbsListView.setItemChecked() вызывает ActionMode Destroy и Recreate?

mGridView.setItemChecked(pPosition, true); 

Но когда вы звоните View.startActionMode() первым, а затем вызвать AbsListView.setItemChecked(), то ActionMode создать на startActionMode() разрушат, и воссоздать новый, setItemChecked().

Мой вопрос: Как избежать этой проблемы при звонке View.startActionMode() сперва?

С нетерпением жду вашего ответа! Благодаря!

ответ

1

Зачем создавать новые? См исходного кода AbsListView.setItemChecked(int position, boolean value) метода, вы можете увидеть следующий код:

// Start selection mode if needed. We don't need to if we're unchecking something. 
    if (value && mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL && mChoiceActionMode == null) { 
     if (mMultiChoiceModeCallback == null || 
       !mMultiChoiceModeCallback.hasWrappedCallback()) { 
      throw new IllegalStateException("AbsListView: attempted to start selection mode " + 
        "for CHOICE_MODE_MULTIPLE_MODAL but no choice mode callback was " + 
        "supplied. Call setMultiChoiceModeListener to set a callback."); 
     } 
     mChoiceActionMode = startActionMode(mMultiChoiceModeCallback); 
    } 

Это означает, что если mChoiceActionMode == null, он будет вызывать startActionMode(mMultiChoiceModeCallback), так будет воссоздать новый ActionMode.

И как исправить? Вот простой способ: использовать рефлекс, чтобы назначить ActionMode для создания startActionMode() частному полю mChoiceActionMode в AbsListView.

private void startActionMode() { 
    // Get the field "mMultiChoiceModeCallback" instance by reflect 
    AbsListView.MultiChoiceModeListener wrapperIns = null; 
    try { 
     Field wrapper = null; 
     wrapper = AbsListView.class.getDeclaredField("mMultiChoiceModeCallback"); 
     wrapper.setAccessible(true); 
     wrapperIns = (AbsListView.MultiChoiceModeListener) wrapper.get(mMessageGridView); 
    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } catch (NoSuchFieldException e) { 
     e.printStackTrace(); 
    } 
    // Start the ActionMode, but not select any item. 
    ActionMode actionMode = mMessageGridView.startActionMode(wrapperIns); 
    // Assign actionMode to field "mChoiceActionMode" by reflect 
    try { 
     Field mChoiceActionMode = null; 
     mChoiceActionMode = AbsListView.class.getDeclaredField("mChoiceActionMode"); 
     mChoiceActionMode.setAccessible(true); 
     mChoiceActionMode.set(mMessageGridView, actionMode); 
    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } catch (NoSuchFieldException e) { 
     e.printStackTrace(); 
    } 
} 

Почему здесь мы используем обертку? Потому что AbsListView.setMultiChoiceModeListener(MultiChoiceModeListener listener) обернет наш mMultiChoiceModeListener, поэтому мы не сможем использовать его напрямую.

Смежные вопросы