【问题标题】:How to enable recyclerview OnItemClickListener after a menu item selection?如何在菜单项选择后启用 recyclerview OnItemClickListener?
【发布时间】:2020-05-02 03:47:45
【问题描述】:

我有一个片段,它包含一个 recyclerview,它有一个交错的网格布局管理器,视图持有者只有一个图像。我试图使它在选择菜单选项(删除图标)后为 recyclerView 启用 onItemClickListener 以便只需点击它们就可以删除图像。此外,我将删除图标替换为停止图标,然后禁用 onItemClickListener。在选择菜单项后,我无法让 onItemClickListener 执行与删除有关的代码,但是当此代码仅在 Fragment 的 onCreateView 方法中时,onItemClickListener 工作得很好。

这是我的适配器类中 ViewHolder 和 onClick 接口的代码:

public class PhotoListViewHolder extends RecyclerView.ViewHolder {

        SquareImageView imageView;

        public PhotoListViewHolder (@NonNull View itemView, OnItemClickListener listener) {
            super(itemView);

            imageView = itemView.findViewById(R.id.image);

            itemView.setOnClickListener(v -> {
                if (listener != null) {
                    int position = getAdapterPosition();
                    if (position != RecyclerView.NO_POSITION) {

                        listener.onItemClick(position);
                    }
                }
            });
        }

    }
public interface OnItemClickListener {
        void onItemClick(int position);

    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        this.listener = listener;
    }

    public OnItemClickListener getListener() {
        return listener;
    }

这是处理菜单项的代码以及如何在片段中删除内容

@Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {

        switch(item.getItemId()) {

            case R.id.delete_items:
                Toast.makeText(getContext(), "Tap an image to delete it", Toast.LENGTH_SHORT).show();
                adapter.setOnItemClickListener(this);
                Log.d(TAG, "start-" + adapter.getListener());
                deleteItem.setVisible(false);
                stopDelete.setVisible(true);
                return true;

            case R.id.stop_selection:

                adapter.setOnItemClickListener(null);
                Log.d(TAG, "stop-" + adapter.getListener());
                currDelete = END_DELETE;
                stopDelete.setVisible(false);
                deleteItem.setVisible(true);

                return true;
            default:
                return super.onOptionsItemSelected(item);
        }

    }
@Override
    public void onItemClick(int position) {
        delete(position);
    }

删除逻辑:

 private void delete(int position) {

        Log.d(TAG, "delete: " + position);
        photoList.removePhoto(position);
        adapter.notifyDataSetChanged();
        savePhotos();
    }

正如我所说,当刚刚在片段的 onCreateView 方法中启动 onItemClickListener 时,图像删除得很好,但是当“动态”这样做时,即使 onItemClickListener 正在被创建和销毁,它也不起作用。日志:

2020-05-01 12:51:32.518 8719-8777/com.streetxportrait.android.planrr D/EGL_emulation: eglMakeCurrent: 0xd8e1a240: ver 3 0 (tinfo 0xd8e0f1c0)
2020-05-01 12:51:32.531 8719-8777/com.streetxportrait.android.planrr D/EGL_emulation: eglMakeCurrent: 0xd8e1a240: ver 3 0 (tinfo 0xd8e0f1c0)
2020-05-01 12:51:52.869 8719-8719/com.streetxportrait.android.planrr D/Grid-fragments: stop-null
2020-05-01 12:58:41.889 8719-8719/com.streetxportrait.android.planrr D/Grid-fragments: start-GridFragment{5a15f1} (3a58a131-1b5e-4fd5-8369-754fb2750bf8) id=0x7f080141 android:switcher:2131231041:0}
2020-05-01 12:58:41.929 8719-8777/com.streetxportrait.android.planrr D/EGL_emulation: eglMakeCurrent: 0xd8e1a240: ver 3 0 (tinfo 0xd8e0f1c0)
2020-05-01 12:58:41.936 8719-8777/com.streetxportrait.android.planrr D/EGL_emulation: eglMakeCurrent: 0xd8e1a240: ver 3 0 (tinfo 0xd8e0f1c0)
2020-05-01 12:58:52.868 8719-8719/com.streetxportrait.android.planrr D/Grid-fragments: stop-null

我还尝试通过视图中的常规按钮启用和禁用侦听器,以及异步执行此操作,但是这些都不起作用。

这是异步尝试的代码:

 private void testWhatever() {


        AsyncTask.execute(() -> {
            while (true) {
                Log.d(TAG, "testWhatever: Current: " + currDelete);

                if (currDelete == START_DELETE) {
                    adapter.setOnItemClickListener(this);
                    Log.d(TAG, "testWhatever: start-" + adapter.getListener());
                }
                else if (currDelete == END_DELETE) {
                    adapter.setOnItemClickListener(null);
                    Log.d(TAG, "testWhatever: stop-" + adapter.getListener());
                }

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }

不能动态启用和禁用 onClickListeners 吗?或者有谁知道这里发生了什么?

【问题讨论】:

    标签: java android android-fragments android-recyclerview


    【解决方案1】:

    在fragment的onCreate()调用setHasOptionsMenu(true)通知框架fragment想要处理选项菜单。

    【讨论】:

    • 对不起,忘了说我已经这样做了。菜单项和所有内容都显示正常,只是单击不起作用的项目。
    • 然后我怀疑问题是由于您在视图构造函数中设置 itemview onCLickListener 的方式导致的变量引用问题。尝试在 onBind() 方法下设置 itemview 点击监听器。
    • 你的意思是在主适配器类的onBindViewHolder方法中吗?或者我应该在 viewHolder 类中创建一个名为 onBind 的新方法?
    • 是在onBindViewMethod下,直接引用OnItemClickListener。在 Java 中,您不能更改作为参数传入方法的对象引用的值。这意味着在您的情况下,即使您稍后更改原始 OnItemClickLister 引用的值,itemview onClickListeners 仍将继续引用最初传递给 viewholder 构造函数的值(为空)。这是一个微妙但重要的问题。检查处理此问题的线程:stackoverflow.com/a/40501/10766098
    猜你喜欢
    • 2023-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多