Long-Click 在 Android 7 设备上触发 Listview 的上下文菜单和选择

Long-Click Triggers both Listview's Context Menu and Selection on Android 7 Device

我有一个 ExpandableListView,我为其实施了选择 (short-click) 和删除 (long-click)。短列表项点击由 onChildClick() 处理,长点击由 onCreateContextMenu() 处理。

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);

    ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo;
    mDeleteItemGroup = ExpandableListView.getPackedPositionGroup(info.packedPosition);
    mDeleteItemChild = ExpandableListView.getPackedPositionChild(info.packedPosition);

    menu.setHeaderTitle("some title");
    MenuInflater inflater = mActivity.getMenuInflater();
    inflater.inflate(R.menu.menu_my_view_context, menu);
}

上面显示了上下文菜单代码,它很好地处理了长按。问题是缺乏风格化,它会在某些设备上截断较长的标题。所以我使用自定义对话框而不是标准上下文菜单如下:

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);

    ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo;
    mDeleteItemGroup = ExpandableListView.getPackedPositionGroup(info.packedPosition);
    mDeleteItemChild = ExpandableListView.getPackedPositionChild(info.packedPosition);

    String title = "some title";

    ConfirmDeletePopupFragment confirmDeletePopupFragment = ConfirmDeletePopupFragment.newInstance(title);
    confirmDeletePopupFragment.setTargetFragment(this, 0);
    confirmDeletePopupFragment.show(getActivity().getSupportFragmentManager(), "tag");
}

这在除 Nexus 5X 以外的所有设备上都能很好地工作 运行 Android 7. 在这里,长按会触发上下文菜单和通过 onChildClick 进行的选择,这显然是不是我想要的。

如何在仍在使用我的自定义对话框的同时阻止项目选择。

我可以提供我当前感觉不太理想的解决方案或解决方法,因为它通过用我的自定义对话框替换上下文菜单来修补我破坏的东西。想法是在删除处理开始时静音选择处理,并在对话框的回调中取消静音。

这可行,但我不想一开始就破坏它。所以可能有更好的方法。

public class MyListFragment extends ExpandableListFragment implements ConfirmDeletePopupFragment.DialogListener {

    (...)   

    private boolean mMuteSelection = false;

    (...)

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);

        mMuteSelection = true;

        ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo;
        mDeleteItemGroup = ExpandableListView.getPackedPositionGroup(info.packedPosition);
        mDeleteItemChild = ExpandableListView.getPackedPositionChild(info.packedPosition);

        String title = "some title"

        ConfirmDeletePopupFragment confirmDeleteWeakPopupFragment = ConfirmDeletePopupFragment.newInstance(title);
        confirmDeletePopupFragment.setTargetFragment(this, 0);
        confirmDeletePopupFragment.show(getActivity().getSupportFragmentManager(), "tag");
    }

    (...)

    @Override
    public boolean onChildClick(ExpandableListView arg0, View arg1, int group, int child, long arg4) {
        super.onChildClick(arg0, arg1, group, child, arg4);

        if (!mMuteSelection) {
            (handle selection)
        }
        return false;
    }

    (...)

    @Override
    public void onDeleteConfirm(boolean delete) {
        if (delete) {
            (handle deletion)
        }
        mMuteSelection = false;
    }
}