关于在外部拿到RecyclerView的viewholder的几种方式

      在实际开发中,我们常常碰到这样的需求,需要在外部拿到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<MyAdapter.MyHolder> {
    private Context context;
    private List<String> 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做不同的事情了。

猜你喜欢

转载自blog.csdn.net/suyimin2010/article/details/84501350