RecyclerView的NO_POSITION 不是异常值!

  1. 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);
            }
        });

 

 

 

 

你可能感兴趣的:(android)