本篇文章主要分析一个具体的adapter类的实现,方便后面抽象的实现。很多东西的学习,都是具体->抽象->具体的过程。
第一步分析常规的一个adapter类的实现:
public class DailyAdapter extends RecyclerView.Adapter<DailyAdapter.DailyHolder>{}
首先看这个这个类,DailyAdapter 是个类名,继承了RecyclerView.Adapter,其中的参数是DailyAdapter.DailyHolder。首先第一个问题来了,RecyclerView.Adapter这是什么?ctrl一下,看看源码说啥了。
* Base class for an Adapter//一个适配器的基础类
*
* <p>Adapters provide a binding from an app-specific data set to views that are displayed * within a {@link RecyclerView}.</p>//适配器提供一个从app特定数据集到视图的绑定,在对应的rv中展示。
//上面的翻译,自己意译的。大佬轻喷。接着第二个问题
DailyAdapter.DailyHolder这个参数是什么?用来干嘛的?
首先DailyAdapter.DailyHolder 是DailyAdapter的内部类,↓这就是它做的事情
static class DailyHolder extends RecyclerView.ViewHolder {
TextView tv;
NetworkImageView iv;
DailyHolder(View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(R.id.item_daily_tv);
iv = (NetworkImageView) itemView.findViewById(R.id.item_daily_iv);
}
}
看一眼,我们可以猜一下,它就是找到item的要填充数据的控件。然后看到它继承了一个RecyclerView.ViewHolder。点进去看看
A ViewHolder describes an item view and metadata about its place within the RecyclerView
这是官方的描述,所以基本确认我们刚刚说的没有错。
接着看:
private Context context; private List<DailyBean.StoriesBean> beanList;
给了两个变量,第一个干嘛的不知道。但是第二个很容易知道,就是我们要绑定的数据。
public DailyAdapter(Context context) {
this.context = context;
beanList = new ArrayList<>();
}
这个一个带参构造器。主要是传了个context,然后new了一个Arraylist,准备装我们的数据。
public void setBeanList(List<DailyBean.StoriesBean> list) {
this.beanList.addAll(list);
notifyDataSetChanged();
}
这个方法用来设置数据。
最后,就是重写了三个方法。
从名字。可以看出分别就是,创建一个viewHolder;绑定viewHolder;得到数据个数;
耐住性子,我们来看看前两个具体操作:
@Override public DailyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new DailyHolder(LayoutInflater.from(context).inflate(R.layout.item_daily, parent, false));
}
返回了一个dailyHolder。一个参数。最终调用给的是inflate()方法,ctrl一下。
public View inflate(int resource, @Nullable ViewGroup root, boolean attachToRoot) {
throw new RuntimeException("Stub!");
}
三个参数,一个是资源id,一个是视图组,一个是 是否与根空间绑定。后面两个参与一般用于自定义View。可以暂时放一放,一般是指就是parent,false。(有兴趣的,可以自行找哥和娘看看)。最后返回一个view。总的来说,就是绑定我们的item布局,然后获得一个VIewHolder
接下来,我们看看一下个重写的方法
@Override
public void onBindViewHolder(DailyHolder holder, int position) {
DailyBean.StoriesBean bean = beanList.get(position);
holder.tv.setText(bean.getTitle());
ImageUtil.loadImage(bean.getImages().get(0), holder.iv,
R.mipmap.ic_launcher_round, R.mipmap.ic_launcher_round);
}
一样,ctrl一下。
Called by RecyclerView to display the data at the specified position. This method should update the contents of the {@link ViewHolder#itemView} to reflect the item at the given position.
大概意思就是,把数据展示到特定的位置,这个方法用来更新itemView里面的数据并且在给定的位置展示出来。
补充一点,点击事件。这个也是常用的。
据我了解,总体有两个方式,一种是在adapter里面写,另一个种就是通过接口回调的方式回到Activity中实现。
Adapter类实现View.OnClickListener,然后在holder里面在对应的控件上设置点击事件。然后在重写的onClick实现具体的点击事件。
最后贴出完整代码:
/**
* @author Quincy
* @Date 2020/2/17
* @Description
*/
public class DailyAdapter extends RecyclerView.Adapter<DailyAdapter.DailyHolder> {
private Context context;
private List<DailyBean.StoriesBean> beanList;
public DailyAdapter(Context context) {
this.context = context;
beanList = new ArrayList<>();
}
public void setBeanList(List<DailyBean.StoriesBean> list) {
this.beanList.addAll(list);
notifyDataSetChanged();
}
@NonNull
@Override
public DailyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (context == null) {
context = parent.getContext();
}
return new DailyHolder(LayoutInflater.from(context)
.inflate(R.layout.item_daily, parent, false));
}
@Override
public void onBindViewHolder(DailyHolder holder, int position) {
DailyBean.StoriesBean bean = beanList.get(position);
holder.tv.setText(bean.getTitle());
ImageUtil.loadImage(bean.getImages().get(0), holder.iv,
R.mipmap.ic_launcher_round, R.mipmap.ic_launcher_round);
}
@Override
public int getItemCount() {
return beanList.size();
}
static class DailyHolder extends RecyclerView.ViewHolder {
TextView tv;
NetworkImageView iv;
DailyHolder(View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(R.id.item_daily_tv);
iv = (NetworkImageView) itemView.findViewById(R.id.item_daily_iv);
}
}
}