0

アクション モードを使用して選択モードを表示しましたが、選択された項目の数が 0 になると、アクション モードが自動的に終了します。ユーザーが戻るキーを押さない限り、選択モードを維持したい。

ModeCallback mModeCallBack = new ModeCallback();
mGridview.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mGridview.setMultiChoiceModeListener(mModeCallBack);

private class ModeCallback implements GridView.MultiChoiceModeListener {
...
}
4

3 に答える 3

3

問題を解決できるかどうかこれを試してください

public void onItemCheckedStateChanged(ActionMode mode, int position,
            long id, boolean checked) {
        if (position == theInitialPosition)
             return; // so we start the action mode but there aren't any items checked
        }
        int selectCount = gridView.getCheckedItemCount();
        if (selectCount > 0) {
            notify = true;              
            dataArray.add(position);
            // if you select another item you'll have two selected items(because of the dummy item) so you need to take care of it 
            switch (selectCount) {
            case 1:
                mode.setSubtitle("One item added ");
                break;
            default:
                mode.setSubtitle("" + selectCount
                        + " items added to favorites");
                break;
            }
        } 

       }

または...

public boolean onItemLongClick(AdapterView<?> parent, View view,
      int position, long id) {

    if (mActionMode != null) {
      return false;
    }
    selectedItem = position;

    // start the action mode using the ActionMode.Callback defined above
    mActionMode = MyActivity.this
        .startActionMode(mActionModeCallback);
    view.setSelected(true);
    return true;
  }
});
      }

      private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {

// called when the action mode is created; startActionMode() was called
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
  // Inflate a menu resource providing context menu items
  MenuInflater inflater = mode.getMenuInflater();
  // assumes that you have "contexual.xml" menu resources
  inflater.inflate(R.menu.xxxxxxx, menu);
  return true;
}
于 2014-03-20T05:05:23.373 に答える
0

この問題は、AbsListView.java の次の柔軟性のないコードに起因します。これは、最後の項目が選択解除されると、ActionMode を無条件に破棄します。

class MultiChoiceModeWrapper implements MultiChoiceModeListener {

    ...

    @Override
    public void onItemCheckedStateChanged(ActionMode mode,
            int position, long id, boolean checked) {
        mWrapped.onItemCheckedStateChanged(mode, position, id, checked);

        // If there are no items selected we no longer need the selection mode.
        if (getCheckedItemCount() == 0) {
            mode.finish();
        }
    }
}

AbsListView は、この手の込んだ動作を合法的に阻止するためのフックを提供しないため、上記のコードによって呼び出されたときに、独自の AbsListView サブクラスから getCheckedItemCount から偽の値を返すという醜いハックに頼らざるを得なくなります。

public class ActionModeHackGridView extends GridView {

    ...

    @Override
    public int getCheckedItemCount() {
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        String name = ActionModeHackGridView.class.getName();
        for (int i = 0; i < stackTrace.length; i++) {

            // First find this method in the stack
            if (stackTrace[i].getClassName().equals(name)
                    && stackTrace[i].getMethodName().equals("getCheckedItemCount")) {

                // ...then examine the caller of this method
                if (stackTrace[i + 1].getClassName().equals(
                        "android.widget.AbsListView$MultiChoiceModeWrapper")
                        && stackTrace[i + 1].getMethodName().equals("onItemCheckedStateChanged")) {

                    // Return a non-zero value so AbsListView doesn't dismiss the ActionMode
                    return 1;
                }
                break;
            }
        }
        return super.getCheckedItemCount();
    }
}

AbsListView サブクラス (ListView など) でも同じハックを使用できます。

于 2014-09-08T15:36:36.620 に答える
0

この問題を修正しました。

@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
    ...
    mCheckedCount = mGridview.getCheckedItemCount();
    // if we unselect the last item, cout is 0, we set it to -1, so it will not exit action mode(because if cout==0, mode.finish()).
    // if we select 1 item, we should plus this "1" back. unless the count will be woring.
    if (mCheckedCount == 0) {
        Utils.modifyFileValue(mGridview, "mCheckedItemCount", mCheckedCount + (checked ? 1 : -1));
    }

    String title = "";
    // we must get the count again, because we changed it.
    mCheckedCount = mGridview.getCheckedItemCount();
    title = mContext.getResources().getString(R.string.select_albums, mCheckedCount > 0 ? mCheckedCount : 0);

    mSelectedConvCount.setText(title);

    ....

    if (checked) {
        mSelectedIds.add(selectedId);
    } else {
        mSelectedIds.remove(selectedId);
    }
}

public static void modifyFileValue(Object object, String filedName, int filedValue) {
    //for my case, I want to get mCheckedItemCount in AbsListView.class, but i passed Gridview, so it should getSuperclass(). because GridView don't have mCheckedItemCount.
    Class classType = object.getClass().getSuperclass();
    Field fild = null;
    try {
        fild = classType.getDeclaredField(filedName);
        fild.setAccessible(true);
        fild.set(object, filedValue);
    } catch (NoSuchFieldException ex) {
        ex.printStackTrace();
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}
于 2014-03-26T06:06:28.653 に答える