前使用RecyclerView.Adapter
,基本就类似套用公式,死步骤,对Adapter
感到既熟悉又陌生。从去年我开始接触学习Android
之时,RecyclerView
已经开始大量被运用,逐步取代ListView
。遂,正好,那就先直接学习RecyclerView.Adapter
相关知识
1. RecyclerView.Adapter适配器
RecyclerView.Adapter
,一个抽象类,并支持泛型
public static abstract class Adapter<VH extends ViewHolder> {
...
}
定义一个MyRecyclerViewAdapter
继承RecyclerView.Adapter
后,Android Stuido
提醒需要重写3个方法,在重写3
个方法前,一般会先定义一个Holder
继承RecycelrView.ViewHolder
,之后直接在MyRecyclerViewAdapter
上,指定泛型就是RecyclerHolder
3个需要必须重写的方法:
方法1:public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
方法2:public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
方法3:public int getItemCount()
在指定了泛型为RecyclerHoler
后,方法2
也会根据泛型改变onBindViewHolder(RecyclerHolder holder, int position)
1.1 onCreateViewHolder(ViewGroup parent, int viewType)创建Holder
源码:
/**
* Called when RecyclerView needs a new {@link ViewHolder} of the given type to represent an item.
*
* @param parent The ViewGroup into which the new View will be added after it is bound to an adapter position.
* @param viewType The view type of the new View.
*
* @return A new ViewHolder that holds a View of the given view type.
*/
public abstract VH onCreateViewHolder(ViewGroup parent, int viewType);
- ViewGroup parent:可以简单理解为
item
的根ViewGroup
,item
的子控件加载在其中 - int viewType:
item
的类型,可以根据viewType
来创建不同的ViewHolder
,来加载不同的类型的item
这个方法就是用来创建出一个新的ViewHolder
,可以根据需求的itemType
,创建出多个ViewHolder
。创建多个itemType
时,需要getItemViewType(int position)
方法配合
1.2 onBindViewHolder(RecyclerHolder holder, int position)绑定ViewHolder
源码:
**
*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.
*
*@param holder The ViewHolder which should be updated to represent the contents of the item at the given position in the data set.
*@param position The position of the item within the adapter's data set.
*/
public abstract void onBindViewHolder(VH holder, int position);
- VH holder:就是在
onCreateViewHolder()
方法中,创建的ViewHolder
- int position:
item
对应的DataList
数据源集合的postion
postion
就是adapter position
,RecycelrView
中item
的数量,就是根据DataList
数据源集合的数量来创建的
1.3 getItemCount()获取Item的数目
源码:
/**
* Returns the total number of items in the data set held by the adapter.
*
* @return The total number of items in this adapter.
*/
public abstract int getItemCount();
这个方法的返回值,便是RecyclerView
中实际item
的数量。有些情况下,当增加了HeaderView
或者FooterView
后,需要注意考虑这个返回值
1.4 简单shi yong
一个最简单的RecyclerViewAdapter
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.RecyclerHolder> {
private Context mContext;
private List<String> dataList = new ArrayList<>();
public MyRecyclerViewAdapter(RecyclerView recyclerView) {
this.mContext = recyclerView.getContext();
}
public void setData(List<String> dataList) {
if (null != dataList) {
this.dataList.clear();
this.dataList.addAll(dataList);
notifyDataSetChanged();
}
}
@Override
public RecyclerHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.id_rv_item_layout, parent, false);
return new RecyclerHolder(view);
}
@Override
public void onBindViewHolder(RecyclerHolder holder, int position) {
holder.textView.setText(dataList.get(position));
}
@Override
public int getItemCount() {
return dataList.size();
}
class RecyclerHolder extends RecyclerView.ViewHolder {
TextView textView;
private RecyclerHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.tv__id_item_layout);
}
}
}
我的个人习惯是单独使用一个setData()
方法将DataList
传递进Adapter
,看到网上有一些博客中会通过构造方法传递。我一般会在网络请求前就初始化Adapter
,当异步网络请求拿到解析过的JSON
数据后,调用这个方法将数据加载进Ada