-
RecyclerView 是当前代码中使用最多的控件之一。
代码编写过程中针对列表的点击事件 很多同学都会在自己定义的RecyclerView.Adapter 里面 onBindViewHolder()中添加监听事件。
这里就会发生一个很神奇的事情, 当你通过getAdapterPosition() 去拿当前选中位置的时候有时候会返回-1;导致程序崩溃
holder.view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/*在这里拿到选中的条目数据*/
list.get(holder.getAdapterPosition());
}
});
测试会偶先这样的崩溃bug。
09-11 17:19:06.690 30454 30454 E AndroidRuntime: java.lang.IndexOutOfBoundsException: Invalid index -1, size is 8
09-11 17:19:06.690 30454 30454 E AndroidRuntime: at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
2. Cause:
进入RecyclerView.java 的 getAdapterPosition()方法:
/**
* 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}.
*
* @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.
*/
public final int getAdapterPosition() {
if (mOwnerRecyclerView == null) {
return NO_POSITION;
}
return mOwnerRecyclerView.getAdapterPositionFor(this);
}
官方明确表示,在layout布局没有完成的时候 会返回 NO_POSITION, 因此 返回-1 是一个很正常的情况。
最好的解决方案,是在使用 getAdapterPosition() 方法的时候 马上进行返回值的检查。
比如:
holder.view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/*在这里拿到选中的条目数据*/
int pos = holder.getAdapterPosition();
if(pos != RecyclerView.NO_POSITION)list.get(pos);
}
});