RecyclerView基本使用
1、RecyclerView
RecyclerView是Android一个更强大的控件,其不仅可以实现和ListView同样的效果,还有优化了ListView中的各种不足。位于包 androidx.recyclerview.widget 中,需要在build.gradle中添加依赖:
implementation "androidx.recyclerview:recyclerview:1.1.0
1.1、使用RecyclerView
首先在布局文件中添加:
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
在Activity中声明RecyclerView对象,注意RecyclerView一定要设置一个LayoutManager,否则不会正常显示。
RecyclerView recyclerView = findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(layoutManager);
现在RecyclerView已经准备完毕,剩下一步工作就是RecyclerView适配器RecyclerView.Adapter的构造。
1.2、RecyclerView.Adapter适配器
自定义的Adapter需要继承自RecyclerView.Adapter类,必须重写三个抽象方法:onCreateViewHolder(),onBindViewHolder()和getItemCount() 。
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return null;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
}
@Override
public int getItemCount() {
return 0;
}
}
- onCreateViewHolder()用于创建ViewHolder实例,并把加载的布局传入到构造函数去,再把ViewHolder实例返回。
- onBindViewHolder()则是用于对子项的数据进行赋值,会在每个子项被滚动到屏幕内时执行。position得到当前项的数据实例。
- getItemCount()返回RecyclerView的子项数目。
Adapter需要提供一些构造方法,用于初始化列表数据:
private List<Information> mInformationLists;
public RecyclerAdapter(List<Information> mInformationLists) {
this.mInformationLists = mInformationLists;
}
或者传入Context、Resource ID等参数,后面在onCrateViewHolder中使用:
private List<Information> mInformationLists;
private Context mContext;
private int mResource;
public RecyclerAdapter(Context context, List<Information> mInformationLists) {
this.mInformationLists = mInformationLists;
this.mContext = context;
}
Adapter适配器中另一个重要的工作是ViewHolder类的构建,同样需要自定义一个ViewHolder继承自RecyclerView.ViewHolder,一般在ViewHolder中定义布局中的控件,以便对其进行设置值等操作,在ViewHolder的构造函数初始化这些控件:
class ViewHolder extends RecyclerView.ViewHolder {
ImageView carImageView;
TextView carTextView;
public ViewHolder(View itemView) {
super(itemView);
this.carImageView = itemView.findViewById(R.id.car_image);
this.carTextView = itemView.findViewById(R.id.car_number);
}
}
接下来需要进行的就是在之前重写的onCreateViewHolder()方法中初始化ViewHolder对象,这个对象就是RecyclerView列表中的item,一般先定义一个View,使用LayoutInfalter从xml布局文件中将布局加载进来,在将view作为参数构造前面定义的ViewHolder并返回。
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.resuorce, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
一般在onBindViewHolder()方法中进行item数据的初始化,先拿到数据集合中第position个对象数据,将其通过ViewHolder实例设置到具体要显示的控件上:
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Information information = informationList.get(position);
holder.imageView.setImageResource(information.getCarNum());
holder.textView.setText(information.getName());
}
最后一个重写的方法getItemCount()只需返回数据集大小即可:
public int getItemCount() {
return informationList.size();
}
1.3、RecyclerView设置Adapter
在Activity中给RecyclerView设置一个适配器即可:
RecycleAdapter adapter = new RecycleAdapter(information);
recyclerView.setAdapter(adapter);
1.4、更新RecyclerView数据
推荐在Adapter类中添加更新数据的方法,封装好了。同时注意,更新列表的数据每次都需要notifyDataSetChanged(),通知界面去更新,否则会出错。而且不要一个一个的去更新、添加、删除数据项,可能会出错。最好一次性更新数据,统一更新数据。
public void updateDataSet(List<Data> dataLists) {
mList.clear();
mList.addAll(dataLists);
notifyDataSetChanged();
}
在Activity中改变数据只需要,通过Adapter实例调用上面的方法,将需要更新的数据作为参数放进去更新即可。
2、RecyclerView多类型Item显示
RecyclerView如果只是这样使用就太大材小用,不如用ListView,RecyclerView重要的一个功能是同一个列表加载不同的View item。
2.1、重写getItemViewType()方法
这个方法会在onCreateViewHolder(ViewGroup parent, int viewType)调用时自动调用,注意其中传入一个viewTyoe参数,这个正是重写getItemViewType()方法返回值,根据这个值的不同去加载不同类型的布局,创建并返回不同类型的ViewHolder对象:
public int getItemViewType(int position) {
if (position == 1) {
return TYPE_FIRST;
} else if (position == 2) {
return TYPE_SECOND;
} else if (position == 3) {
return TYPE_THIRD;
} else {
return TYPE_OTHER;
}
}
如何使用呢,很简单,判断onCreateViewHolder(ViewGroup parent, int viewType)方法中的viewType参数的值去加载不同类型的布局item界面:
在onBindViewHolder(RecyclerView.ViewHolder holder, int position)方法中,根据position参数的不同,判断不同位置上的item类型,给不同类型的ViewHolder赋予不同的值:
这要就可以加载多种类型的item,如下图所示。其实还可以有更加巧妙和复杂的方式,List<BaseObject>数据集中保存基类对象,给不同的Item赋予不同的派生类对象中的值。
3、RecyclerView水平布局和瀑布流布局
给RecyclerView一个水平的LinearLayoutManager,就可以让RecyclerView水平横向放置
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(layoutManager);
同样,声明一个网格瀑布流布局管理器StaggeredGridLayoutManager,设置一行摆放item的数量和方向
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(layoutManager);
参考博客:
《关于RecyclerView你知道的不知道的都在这了》
《RecyclerView添加监听事件》
《RecyclerView如何使用正确notifyItemRemoved》
《自定义Recyclerview.ItemDecoration实现分组吸顶效果》