(android) getAdapterPosition() 是否仅在 OnClick() 内部起作用?
(android) Does getAdapterPosition() only work inside OnClick()?
我现在很困惑,因为 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
中设置点击侦听器,我认为它应该可以工作。
原因在源代码的注释文档中已经提到。
- Note that if you've called {@link RecyclerView.Adapter#notifyDataSetChanged()}, until the
* next layout pass, the return value of this method will be {@link #NO_POSITION}.
这意味着如果 Adapter
仍处于充气状态,那么 getAdapterPosition
将 return -1
。如果您阅读评论,它用于计算 ViewHolder
的位置以对用户 UI 操作(点击、触摸等)做出反应。
您对匿名 class 所做的是您设置了全局 属性 和 getAdapterPosition()
,它将在初始化时设置。它有时可以是 -1,具体取决于适配器状态。
如果您使用 notifyItemRemoved()
也会给您带来麻烦,因为它不会为其他位置更新已保存的 属性。假设你在适配器中有 0..10 个项目,你在删除 0 后调用 notifyItemRemoved(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);
}
}
});
我现在很困惑,因为 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
中设置点击侦听器,我认为它应该可以工作。
原因在源代码的注释文档中已经提到。
- Note that if you've called {@link RecyclerView.Adapter#notifyDataSetChanged()}, until the * next layout pass, the return value of this method will be {@link #NO_POSITION}.
这意味着如果 Adapter
仍处于充气状态,那么 getAdapterPosition
将 return -1
。如果您阅读评论,它用于计算 ViewHolder
的位置以对用户 UI 操作(点击、触摸等)做出反应。
您对匿名 class 所做的是您设置了全局 属性 和 getAdapterPosition()
,它将在初始化时设置。它有时可以是 -1,具体取决于适配器状态。
如果您使用 notifyItemRemoved()
也会给您带来麻烦,因为它不会为其他位置更新已保存的 属性。假设你在适配器中有 0..10 个项目,你在删除 0 后调用 notifyItemRemoved(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);
}
}
});