关于在外部拿到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做不同的事情了。

在 Android 中,RecyclerView 是一个非常常用的控件,用于展示大量的数据列表。在使用 RecyclerView 时,我们需要创建 ViewHolder 和 Adapter。 ViewHolder 是一个容器,用于存放 RecyclerView 中的每个 item 的视图,我们可以在其中找到 item 中的各个控件。Adapter 则是将数据与 ViewHolder 绑定在一起,用于将数据显示在 RecyclerView 上。 在 RecentApp 中,我们可以按照以下步骤使用 RecyclerViewViewHolder 和 Adapter: 1. 在 XML 布局文件中添加 RecyclerView 控件: ``` <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 2. 创建 ViewHolder 类,用于存放 RecyclerView 中的 item 视图: ``` public class RecentAppViewHolder extends RecyclerView.ViewHolder { public TextView appName; public ImageView appIcon; public RecentAppViewHolder(@NonNull View itemView) { super(itemView); appName = itemView.findViewById(R.id.app_name); appIcon = itemView.findViewById(R.id.app_icon); } } ``` 3. 创建 Adapter 类,用于将数据与 ViewHolder 绑定在一起: ``` public class RecentAppAdapter extends RecyclerView.Adapter<RecentAppViewHolder> { private List<AppInfo> appInfoList; public RecentAppAdapter(List<AppInfo> appInfoList) { this.appInfoList = appInfoList; } @NonNull @Override public RecentAppViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_recent_app, parent, false); return new RecentAppViewHolder(view); } @Override public void onBindViewHolder(@NonNull RecentAppViewHolder holder, int position) { AppInfo appInfo = appInfoList.get(position); holder.appName.setText(appInfo.getName()); holder.appIcon.setImageDrawable(appInfo.getIcon()); } @Override public int getItemCount() { return appInfoList.size(); } } ``` 4. 在 Activity 或 Fragment 中初始化 RecyclerViewViewHolder 和 Adapter: ``` RecyclerView recyclerView = findViewById(R.id.recycler_view); RecentAppAdapter adapter = new RecentAppAdapter(appInfoList); recyclerView.setAdapter(adapter); recyclerView.setLayoutManager(new LinearLayoutManager(this)); ``` 这样,就可以在 RecentApp 中使用 RecyclerViewViewHolder 和 Adapter 来显示最近打开的应用程序了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值