首页 > 解决方案 > (android) getAdapterPosition() 是否只能在 OnClick() 中工作?

问题描述

我现在很困惑,因为getAdapterPosition()

我问这个的原因是因为getAdapterPosition()根据呼叫位置工作。

它适用于 Anonymous Obect's OnClick(). 但如果它Anonymous Obect's Field存在,它就不起作用。

此时的值为-1

有什么问题?

这是代码

适配器.java ( RecyclerView Adpater)

part.setOnClickListener(new View.OnClickListener() {
                int position = getAdapterPosition(); // didn't work
                @Override
                public void onClick(View v) {
                    int position = getAdapterPosition(); // work well
                    if(select == false) {
                        part.setBackgroundColor(context.getResources().getColor(R.color.teal_700));;
                        select = true;
                    }
                    else {
                        part.setBackgroundColor(context.getResources().getColor(R.color.white));;
                        select = false;
                    }
                    listener.OnItemClick(v, position); // or OnItemClick(v, getAdapterPosition()) works well, too
                }
            });

DialogFragment.java(错误位置)

dialogAdapter.setOnItemClickListener(new DialogItemAdapter.OnDialogItemClickListener() {
            @Override
            public void OnItemClick(View itemView, int pos) {
                Log.d(TAG, "OnItemClick: ");
                String data = dialogAdapter.getItem(pos).getPart(); // ERROR

            }
        });

这是Java的语法问题吗?

请帮我。

谢谢

标签: androidandroid-recyclerviewandroid-adapter

解决方案


源代码的注释文档中已经提到了这样做的原因。

  • 请注意,如果您调用了 {@link RecyclerView.Adapter#notifyDataSetChanged()},直到 * 下一个布局通过,此方法的返回值将是 {@link #NO_POSITION}。

这意味着如果Adapter仍处于充气状态,getAdapterPosition则将返回-1。如果您阅读评论,它用于计算ViewHolder对用户 UI 操作(单击、触摸等)做出反应的位置。

您对匿名类所做的事情已经设置了一个全局属性,getAdapterPosition()该属性将在初始化时设置。它有时可以是 -1 ,具体取决于 Adapters State 。

如果您使用它也会给您带来麻烦,notifyItemRemoved()因为它不会更新其他位置的已保存属性。假设您在适配器中有 0..10 个项目,并且您notifyItemRemoved(0)在 0 被删除后调用,您的匿名属性仍将保留1..10,因为他们没有收到通知,最终将在ArrayIndexOutOfBound. 这就是为什么你应该用它getAdapterPosition()来计算动作时的位置。

也只是为了安全起见,请始终检查NO_POSTION.

part.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int position = getAdapterPosition();
            if (position != RecyclerView.NO_POSITION) {
                if (select == false) {
                    part.setBackgroundColor(context.getResources().getColor(R.color.teal_700));
                    select = true;
                } else {
                    part.setBackgroundColor(context.getResources().getColor(R.color.white));
                    select = false;
                }
                listener.OnItemClick(v, position);
            }
        }
    });

推荐阅读