问题描述
我现在很困惑,因为getAdapterPosition()
。
我问这个的原因是因为 getAdapterPosition()
根据呼叫位置起作用。
它适用于 Anonymous Obect's OnClick()
。但是如果它存在 Anonymous Obect's Field
,它就不起作用。
此时的值为-1
。
有什么问题吗?
这是代码
Adapter.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 的语法问题吗?
请帮帮我。
谢谢
解决方法
来自文档:
/**
* ...
* @return The adapter position of the item if it still exists in the adapter.
* {@link RecyclerView#NO_POSITION} if item has been removed from the adapter,* {@link RecyclerView.Adapter#notifyDataSetChanged()} has been called after the last
* layout pass or the ViewHolder has already been recycled.
*/
所以这意味着 // did not work
行在项目已从适配器中移除或 ViewHolder 已被回收时被调用。换句话说,您的 ViewHolder 当前未显示在您的回收器视图中。
当 // work well
行被调用时,ViewHolder 实际上在回收器视图中处于活动状态。
我怀疑您在 ViewHolder 的构造函数中设置了侦听器,并且当构造函数运行时,viewholder 尚未位于回收器视图中。如果您将点击侦听器设置在 onBindViewHolder
中,我认为它应该可以工作。
原因已经在源码的注释文档中提到了。
- 请注意,如果您调用了 {@link RecyclerView.Adapter#notifyDataSetChanged()},直到 * 下一次布局传递,此方法的返回值将是 {@link #NO_POSITION}。
这意味着如果 Adapter
仍处于膨胀状态,那么 getAdapterPosition
将返回 -1
。如果您阅读评论,它用于计算 ViewHolder
的位置以对用户界面操作(点击、触摸等)做出反应。
您对匿名类所做的事情是使用 getAdapterPosition()
设置全局属性,该属性将在初始化时设置。有时可能是 -1,具体取决于适配器状态。
如果您使用 notifyItemRemoved()
也会给您带来麻烦,因为它不会更新其他位置的已保存属性。假设您在适配器中有 0..10 个项目,并且您在删除 0 后调用 notifyItemRemoved(0)
,您的匿名属性仍将保留 1..10
,因为他们没有收到通知,最终会在 {{1 }} 。这就是为什么您应该使用 ArrayIndexOutOfBound
来计算动作时的位置。
为了安全起见,请始终检查 getAdapterPosition()
。
NO_POSTION