RecyclerView是ListView的升级版,与ListView相比使用更方便效率更高
这里直接借鉴Android群英传的例子来进行说明
一、使用RecyclerView.Adapter进行管理RecyclerView的viewitem进行循环利用viewitem
1、我们新建一个类RecyclerAdapter来继承RecyclerView.Adapter并实现3个接口
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) public void onBindViewHolder(@NonNull ViewHolder holder, int position) public int getItemCount()
onCreateViewHolder用来创建ViewHolder对象,并将对应的view设置给ViewHolder;
onBindViewHolder用来设置当前传进来的holder管理的view
getItemCount返回当前的RecyclerView一共有多少个viewitem
注意:
1、当我们调试的时候会发现onCreateViewHolder只在初始化的时候会调用,在滑动或者增删操作的时候均不会再调用该函数
2、当我们在滑动或者增删操作的时候均会调用该函数
出现第一点的原因是因为RecyclerView可以克隆多个,只需要在初始化的时候调用一个ViewHolder即可
出现第二点的原因是因为viewitem是循环利用,所以当某个item即将出现或者出现的时候需要从cache中拿出一个viewitem来进行设置对应的view内容
二、重写RecyclerView.ViewHolder
重写ViewHolder并支持对应的点击监听事件
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public TextView textView; public ViewHolder(@NonNull View itemView) { super(itemView); textView = (TextView) itemView; textView.setOnClickListener(this); } @Override public void onClick(View v) { if (itemClickListener != null) { itemClickListener.onItemClick(v, getLayoutPosition()); } } }
如上所示,在点击viewitem的时候则会调用onClick
这里在使用getLayoutPosition的时候发现还有一个接口getAdapterPosition
在正常的点击事件中,这两个函数所返回的positon是一样的;那么他们不同的地方是什么呢?
具体区别就是adapter和layout的位置会有时间差(<16ms), 如果你改变了Adapter的数据然后刷新视图, layout需要过一段时间才会更新视图, 在这段时间里面, 这两个方法返回的position会不一样.
getLayoutPosition顾名思义为界面显示的位置
这里先做个实验,假设有3个item,然后点击第一个item,onClick的代码如下所示:
public void onClick(View v) { if (mItemClickListener != null) { for (int i = 0; i < 3; ++i) { int position = getLayoutPosition(); System.out.println("onclick:" + position + ", adapter:" + getAdapterPosition()); if (position > 0) { mData.remove(position); notifyDataSetChanged(); } } } }
该for是模拟某个viewitem被连续点击3次,该log如下所示,打印完这些log之后崩溃
onclick:1, adapter:1
onclick:1, adapter:-1
onclick:1, adapter:-1
为何getLayoutPosition一直返回1,而getAdapterPosition在删除之后界面虽然还没刷新但是已经返回-1了
要查看究竟我们可以看下这两个函数的实现
getLayoutPosition:
public final int getLayoutPosition() { return mPreLayoutPosition == NO_POSITION ? mPosition : mPreLayoutPosition; }
只是简单的判断当前的位置,没有判断当前viewitem所在的状态
getAdapterPosition:
public final int getAdapterPosition() { if (mOwnerRecyclerView == null) { return NO_POSITION; } return mOwnerRecyclerView.getAdapterPositionFor(this); } int getAdapterPositionFor(ViewHolder viewHolder) { if (viewHolder.hasAnyOfTheFlags(ViewHolder.FLAG_INVALID | ViewHolder.FLAG_REMOVED | ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN) || !viewHolder.isBound()) { return RecyclerView.NO_POSITION; } return mAdapterHelper.applyPendingUpdatesToPosition(viewHolder.mPosition); }
如上所示,会判断当前的viewholder是否被标记为删除的状态,如果标记为删除的状态则返回NO_POSITION 即-1
所以使用的时候可以根据自己的需要看是要用getLayoutPosition还是getAdapterPosition
标签:ViewHolder,int,安卓,viewitem,RecyclerView,public,getLayoutPosition From: https://www.cnblogs.com/czwlinux/p/17063424.html