2

直接呼び出すとAbsListView.setItemChecked()うまく動作し、ActionModeが起動して作成されます。

mGridView.setItemChecked(pPosition, true);

しかし、View.startActionMode()最初に を呼び出してから を呼び出すAbsListView.setItemChecked()と、ActionModecreate bystartActionMode()は破棄し、 によって新しいものを再作成しsetItemChecked()ます。

私の質問は次のとおりView.startActionMode()です。最初に電話するときにこの問題を回避するにはどうすればよいですか?

お返事を楽しみにしています!ありがとう!

4

1 に答える 1

1

なぜ新しいものを再作成するのですか?メソッドのソース コードを参照してAbsListView.setItemChecked(int position, boolean value)ください。次のコードが表示されます:</p>

    // 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 を再作成します。

そして、どのように修正するのですか?簡単な方法は次のとおりです。reflect を使用して、ActionMode create bystartActionMode()を のプライベート フィールド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();
    }
}

ここでラッパーを使用する理由 mMultiChoiceModeListenerAbsListView.setMultiChoiceModeListener(MultiChoiceModeListener listener)をラップするため、直接使用することはできません。

于 2015-03-04T09:41:55.720 に答える