导语
As we all know-众所周知,RecycleView 在展示数据列表的页面替换Listview的趋势已然出现,现在网络上关于它的资料也是铺天盖地,我就不再介绍如何使用了。但是,我对RecycleView的Adapter还是比较感兴趣的,因为懂得了Adapter,对于RecycleView的扩展及优化会很有帮助。这篇文章,先了解一下 onCreateViewHolder调用次数和 onBindViewHolder 之间的暧昧关系。
添加依赖
com.android.support:appcompat-v7:26.1.0
com.android.support:recyclerview-v7:26.1.0
(提示:根据自己android.support 版本去调整recycleView依赖版本)
上代码嘞!
RecyclerViewAdapter.class :继承RecyclerView.Adapter后,会重写三个方法:
public class RecycleViewAdapter extends RecyclerView.Adapter {
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
}
@Override
public int getItemCount() {
return 0;
}
}
onCreateViewHolder()方法,负责承载每个子项的布局。它有两个参数,其中一个是 int viewType;
onBindViewHolder()方法,负责将每个子项holder绑定数据。俩参数分别是RecyclerView.ViewHolder holder, int position;
by the way-顺便说下,该类继承的RecyclerView.Adapter。其实可以加泛型ViewHolder,如下:
public class RecycleViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
}
@Override
public int getItemCount() {
return 0;
}
}
布局文件
item_layout.xml 。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/txt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="xxx"/>
</LinearLayout>
Usually-通常情况下,我们会define一个ViewHolder类喔,这样方便绑定数据和扩展。
public Context mContext;
static class ViewHolde extends RecyclerView.ViewHolder {
TextView txt;
public ViewHolde(View itemView) {
super(itemView);
txt = itemView.findViewById(R.id.txt);
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View item = LayoutInflater.from(mContext).inflate(R.layout.item_layout , parent ,false);
return new RecyclerAdapter.ViewHolde(item);
}
绑定数据
data.class 实体类。(动手敲代码的复制即可)
public class data {
/**
* 名字
*/
private String name;
/**
* 子项类型
* 1: 标题
* 2:普通
*/
private int type;
public data(String name, int type) {
this.name = name;
this.type = type;
}
public String getName() {
return name;
}
public int getType() {
return type;
}
/**
* 存储的数据列表
*/
private static List<data> mDataList;
public static List<data> getDataList() {
if (mDataList == null){
mDataList = new ArrayList<>();
data bean1 = new data("热销推荐",1);
mDataList.add(bean1);
mDataList.addAll(foods("热销零食"));
data bean2 = new data("菜品",1);
mDataList.add(bean2);
mDataList.addAll(foods("小菜一碟"));
data bean3 = new data("主食",1);
mDataList.add(bean3);
mDataList.addAll(foods("馒头,嗷~"));
data bean4 = new data("饮料",1);
mDataList.add(bean4);
mDataList.addAll(foods("啤酒饮料矿泉水"));
}
return mDataList;
}
/**
* 循环存储食物名字
* @param foodName
* @return
*/
private static List<data> foods(String foodName){
List<data> foods =new ArrayList<>();
data food = null;
for (int i = 0 ; i < 10 ; i++){
food = new data(foodName+"("+i+")",2);
foods.add(food);
}
return foods;
}
}
索性,我就把Adapter里的全部代码贴出来咯!其实代码很简单,如下:
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
/**
* context
*/
public Context mContext;
/**
* 集合
*/
public List<data> mDatas = new ArrayList<>();
/**
* data
*/
public data mData;
public RecyclerAdapter(Context mContext, List<data> mDatas) {
this.mContext = mContext;
this.mDatas = mDatas;
}
static class ViewHolde extends RecyclerView.ViewHolder {
TextView txt;
public ViewHolde(View itemView) {
super(itemView);
txt = itemView.findViewById(R.id.txt);
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View item = LayoutInflater.from(mContext).inflate(R.layout.item_layout , parent ,false);
Log.d("aaa","onCreateViewHolder————"+viewType);
if (viewType == 1){//标题
item.setTag(true);
}else{
item.setTag(false);
}
return new ViewHolde(item);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof ViewHolde){
mData =mDatas.get(position);
((ViewHolde) holder).txt.setText(mData.getName());
Log.d("aaa","onBindViewHolder————"+mData.getName());
if (mData.getType() == 1){
((ViewHolde) holder).txt .setTextColor(mContext.getColor(R.color.colorAccent));
((ViewHolde) holder).txt .setBackgroundColor(mContext.getColor(R.color.colorPrimary));
((ViewHolde) holder).txt .setTextSize(20);
}
}
}
@Override
public int getItemViewType(int position) {
Log.d("aaa","getItemViewType————"+ mDatas.get(position).getType());
return mDatas.get(position).getType();
}
@Override
public int getItemCount() {
return mDatas.size();
}
}
运行结果
public class MainActivity extends AppCompatActivity {
RecyclerView mRecyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView =findViewById(R.id.recyclelist);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setAdapter(new RecyclerAdapter(this, data.getDataList()));
}
}
好了,我们先运行看效果吧。
估计,看官们看代码也已经不耐烦了吧?
看完效果,我们接着说。
Log日志分析
其实,我们已经知道答案了,因为最后我把dapter代码贴出后,大家可能没注意,我在关键地方都标有log输出。
扫描二维码关注公众号,回复:
2017854 查看本文章
打印如下:
04-26 16:07:45.535 D/aaa: getItemViewType————1
04-26 16:07:45.540 D/aaa: onCreateViewHolder————1
04-26 16:07:45.541 D/aaa: onBindViewHolder————热销推荐
04-26 16:07:45.544 D/aaa: getItemViewType————2
04-26 16:07:45.547 D/aaa: onCreateViewHolder————2
04-26 16:07:45.547 D/aaa: onBindViewHolder————热销零食(0)
04-26 16:07:45.549 D/aaa: getItemViewType————2
04-26 16:07:45.551 D/aaa: onCreateViewHolder————2
04-26 16:07:45.552 D/aaa: onBindViewHolder————热销零食(1)
04-26 16:07:45.553 D/aaa: getItemViewType————2
04-26 16:07:45.556 D/aaa: onCreateViewHolder————2
04-26 16:07:45.556 D/aaa: onBindViewHolder————热销零食(2)
04-26 16:07:45.557 D/aaa: getItemViewType————2
04-26 16:07:45.560 D/aaa: onCreateViewHolder————2
04-26 16:07:45.560 D/aaa: onBindViewHolder————热销零食(3)
04-26 16:07:45.561 D/aaa: getItemViewType————2
04-26 16:07:45.563 D/aaa: onCreateViewHolder————2
04-26 16:07:45.564 D/aaa: onBindViewHolder————热销零食(4)
04-26 16:07:45.565 D/aaa: getItemViewType————2
04-26 16:07:45.568 D/aaa: onCreateViewHolder————2
04-26 16:07:45.568 D/aaa: onBindViewHolder————热销零食(5)
04-26 16:07:45.569 D/aaa: getItemViewType————2
04-26 16:07:45.572 D/aaa: onCreateViewHolder————2
04-26 16:07:45.572 D/aaa: onBindViewHolder————热销零食(6)
04-26 16:07:45.574 D/aaa: getItemViewType————2
04-26 16:07:45.576 D/aaa: onCreateViewHolder————2
04-26 16:07:45.576 D/aaa: onBindViewHolder————热销零食(7)
04-26 16:07:45.577 D/aaa: getItemViewType————2
04-26 16:07:45.579 D/aaa: onCreateViewHolder————2
04-26 16:07:45.579 D/aaa: onBindViewHolder————热销零食(8)
04-26 16:07:45.580 D/aaa: getItemViewType————2
04-26 16:07:45.582 D/aaa: onCreateViewHolder————2
04-26 16:07:45.582 D/aaa: onBindViewHolder————热销零食(9)
04-26 16:07:45.584 D/aaa: getItemViewType————1
04-26 16:07:45.586 D/aaa: onCreateViewHolder————1
04-26 16:07:45.587 D/aaa: onBindViewHolder————菜品
04-26 16:07:45.589 D/aaa: getItemViewType————2
04-26 16:07:45.591 D/aaa: onCreateViewHolder————2
04-26 16:07:45.592 D/aaa: onBindViewHolder————小菜一碟(0)
04-26 16:07:45.593 D/aaa: getItemViewType————2
04-26 16:07:45.596 D/aaa: onCreateViewHolder————2
04-26 16:07:45.596 D/aaa: onBindViewHolder————小菜一碟(1)
04-26 16:07:45.597 D/aaa: getItemViewType————2
04-26 16:07:45.599 D/aaa: onCreateViewHolder————2
04-26 16:07:45.599 D/aaa: onBindViewHolder————小菜一碟(2)
04-26 16:07:45.601 D/aaa: getItemViewType————2
04-26 16:07:45.603 D/aaa: onCreateViewHolder————2
04-26 16:07:45.603 D/aaa: onBindViewHolder————小菜一碟(3)
很简单,我来分析一波~~ ^_^
首先,日志只打印出页面展示出的所有子项。说明啥?嗯,答案跟你想的一样。
其次,总结方法执行规律: getItemViewType 》 onCreateViewHolder 》 onBindViewHolder
最后,我们居然不小心知道了onCreateViewHolder 和 onBindViewHolder调用次数是保持一致的。它们为每个子项都执行了一次。
结尾,送菊花。
最后说一句话,下面一篇文章是把这个案例升级,实现可以吸附在顶部的列表小标题。欢迎各位看官去研究一波。
Android 使用RecycleView实现吸附小标题的Demo(附源码)