A flexible view for providing a limited window into a large data set.
以上是Google api对于RecyclerView的介绍,RecyclerView用于为大型数据集提供有限的窗口,与ListView一样是一个列表类型的控件,不过RecyclerView比ListView更加灵活,RecyclerView不进可以在垂直方向显示列表,还可以在水平方向显示列表,亦可以像GridView一样显示网格列表。
RecyclerView的使用
RecyclerView和ListView的基本使用时一致的,都是需要一个数据源,一个列表样式适配器,不过相较于ListView,RecyclerView需要加入依赖,因为RecyclerView并不是原生的控件,而是放在support包里面的:
compile 'com.android.support:recyclerview-v7:28.0.0'
加入依赖包之后就可以在布局文件xml里面正常引用了:
<android.support.v7.widget.RecyclerView
android:id="@+id/recycle_data"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_white"/>
RecyclerView的布局Manager
之前也有提到过,RecyclerView可以实现ListView一样的列表样式,也可以实现GridView一样的网格样式,更可以实现RecyclerView独有的瀑布流样式(当然自定义也可以实现瀑布流),都要归功于RecyclerView的LayoutManager:
- LinerLayoutManager(线性):以垂直或者水平列表方式展示Item
- GridLayoutManager (网格):以网格方式展示Item
- StaggeredGridLayoutManager(瀑布流): 以瀑布流方式展示Item
简单的使用方法如下所示:
//垂直方向的线性列表布局
LinearLayoutManager verticalLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
//水平方向的线性列表布局
LinearLayoutManager horizontalLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
//网格样式布局
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3);
//瀑布流布局
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(verticalLayoutManager);
当然,每一个Manager的参数有什么含义,感兴趣的可以查看源码更深入的去了解,但是基本上重写RecyclerView去实现更加多样的效果的新控件,也基本上是不会动Manager的。
RecyclerView的适配器Adapter
之前有提到ListView的适配器Adapter的使用和相关的优化方式,而RecyclerView的Adapter都完美的继承并优化了ListView的适配器的优点。但是,RecyclerView的适配器还是有些地方没有实现,就是每一项的点击事件,按照Google官方给的答复是,使用者可以自定义点击事件,更加灵活方便,Adapter的简单使用如下:
public class RecyclerTestAdapter extends RecyclerView.Adapter<RecyclerTestAdapter.ViewHolder> {
private List<String> dataList;
private Context mContext;
private OnTestAdapterClickListener mOnTestAdapterClickListener;
public RecyclerTestAdapter(List<String> dataList, Context context) {
this.dataList = dataList;
mContext = context;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(mContext).inflate(R.layout.item_recycler_view, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, final int i) {
viewHolder.tvText.setText(dataList.get(i));
viewHolder.llRoot.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mOnTestAdapterClickListener != null) {
mOnTestAdapterClickListener.onItemClick(i);
}
}
});
viewHolder.tvText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mOnTestAdapterClickListener != null) {
mOnTestAdapterClickListener.onTextClick(i);
}
}
});
}
@Override
public int getItemCount() {
return dataList.size();
}
public void setOnTestAdapterClickListener(OnTestAdapterClickListener onTestAdapterClickListener) {
mOnTestAdapterClickListener = onTestAdapterClickListener;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
LinearLayout llRoot;
TextView tvText;
public ViewHolder(@NonNull View itemView) {
super(itemView);
llRoot = itemView.findViewById(R.id.item_root);
tvText = itemView.findViewById(R.id.tv_item_text);
}
}
public interface OnTestAdapterClickListener{
void onItemClick(int position);
void onTextClick(int position);
}
}
当然更复杂的使用,需要多重写一些adapter的其他方法,同一个列表根据下标,或者是其他的什么标识,根据情况来显示不同样式的布局,等等各种各样的深度使用,这都需要深入的去查看源码,研究学习使用。
RecyclerView的列表decoration和animator
RecyclerView的列表每一项的分割线显示和ListView的显示不一样,ListView的分隔符可以在xml属性里面设置,RecyclerView的分隔符使用的是单独的一个类ItemDecoration,这是一个抽象类,如果想要自定义每一项之间的分隔符,就需要继承ItemDecoration并重写相关方法,注入自己想要的分隔符的效果。并通过add方法,添加到想要该效果的RecyclerView上面去:
recyclerView.addItemDecoration(new TestItemDecoration());
RecyclerView的列表每一项滑出屏幕、滑出屏幕都可以自定义出独特的动画,可以用ItemAnimator这个抽象类,正常情况下,都是不设置,使用的是support包里面的默认动画DefaultItemAnimator类,也可以继承ItemAnimator类并重写相关方法,只需要通过set方法设置一下就可以了:
recyclerView.setItemAnimator(new DefaultItemAnimator());
网友评论