在实际开发中,我们常常碰到这样的需求,需要在外部拿到RecyclerView 中的viewHoler,从而动态的修改UI,在RecyclerView中,我们需要自己封装点击事件,一般的做法是在recyclerview每一次bind的时候我们给viewholder的itemview注册监听事件,典型写法如下:
@Override
public void onBindViewHolder(final MyHolder holder, final int position) {
Log.i("bind", list.size() + "");
holder.tv.setText(list.get(position));
if(listener != null){
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onclick(holder,position,list.get(position));
}
});
}
}
因为点击事件的监听写在这个函数中,而这个函数的参数刚好又有ViewHolder,所以我们可以拿到点击的那一项的viewholder,从而动态的修改那一项的UI;那么如果我们想要从adapter外部拿到其他项的viehodler。我们应该怎么做呢
首先,我们来区分两个函数。
getChildCount()这个函数在api中写的很清楚,它的返回值是attached的child views的个数,那么什么时候view会被attach呢,答案很简单,系统为了节约内存,只对可见的view进行attach,所以返回值其实就是可见的item的个数。
getItemCount() 这个函数写的也很明白,他的返回值是你给recyclerview绑定的item的个数,也就是总的个数,你传进去的list的个数有几个他就返回几。
如下做法是通过layoutManger拿到Viewholder的每一项,只要你ViewHolder中的控件不是私有的,就可以直接拿到他们,改变他们的属性,但是这样做循环的次数必须是manager.getChildCount(),因为这样写只能拿到RecyclerView可见的每一项的Viewholder,如果你的item数量比较多,不可见的item是拿不到的,如果你循环的次数是你传入adapter的list的长度,那么很有可能会报空指针异常,因为不可见的项是拿不到的。
RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
// manager.getItemCount();
// manager.getChildCount();
for (int i = 0; i < manager.getChildCount();i++){
View view = manager.getChildAt(i);
MyAdapter.MyHolder holder = (MyAdapter.MyHolder) recyclerView.getChildViewHolder(view);
}
有时候我们需要在初始化adapter时对不同的item进行不同的操作那么我们应该怎么做呢。我们知道当recyclerview绑定item的时候都会调用onbindViewHolder()方法,那么我们只需要控制不同的item进行不同的操作就可以了,具体的方法类似于线程的中断,你一定知道,如果需要中断一个线程,最好的方法是通过标记位中断,也就是说从外部改变线程中函数的运行条件,这样线程就能自然而然的中断,那么在这里,我们只需要维系一个变量,从外部通过set方法来改变变量的值,从而能够从外部修改item的属性。
public class MyAdapter extends RecyclerView.Adapter {
private Context context;
private List list;
private ItemClickListener listener;
private int which;
@Override
public void onBindViewHolder(final MyHolder holder, final int position) {
if(which == position){
//to do something
}
}
}
这样我们就可以操作不同的item做不同的事情,当然这里只是操作一个item做不同的事情,如果是多个item做不同的事情,那么把变量换成list即可
在外部我们只需要
adapter.setWhich(int Which);
recyclerView.setAdapter(adapter);
就可以控制不同的item做不同的事情了。