前言
RecyclerView是Android 5.0之后推出的列表类控件,具有高度的解耦性和灵活性。通过使用合适的LayoutManager,可以实现ListView、横向ListView、GridView和瀑布流列表的效果。本文将对RecyclerView的相关知识点进行详细讲解。
基本用法
使用步骤
RecyclerView是支持库中的控件,因此在使用前需要先在build.gradle
文件中添加依赖,如下:
implementation 'com.android.support:recyclerview-v7:26.0.0-beta1'
注意: AndroidStudio在升级到3.0
版本后,不再使用compile
关键字引入依赖库,而改用implementation
关键字。
配置好依赖后,就可以正式开始使用RecyclerView了。首先,提供列表项(Item)的布局文件,本例中命名为recycler_view_item.xml
,代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#f36c60">
<TextView
android:id="@+id/text_view_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:textSize="16sp"
android:textColor="#fff"
android:gravity="center"/>
</LinearLayout>
RecyclerView和ListView类似,都是借助Adapter访问数据源,因此还需要实现自己的适配器,示例代码如下:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{
private List<String> dataList;//数据源
private LayoutInflater inflater;//布局解析器
public RecyclerViewAdapter(List<String> dataList){
this.dataList = dataList;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {
if(inflater==null){
//避免多次初始化
inflater=LayoutInflater.from(parent.getContext());
}
View itemView=inflater.inflate(R.layout.recycler_view_item,parent,false);
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position){
final String itemContent=dataList.get(position);
holder.textView.setText(itemContent);
}
@Override
public int getItemCount() {
return dataList.size();
}
//自定义ViewHolder
static class ViewHolder extends RecyclerView.ViewHolder{
private TextView textView;
public ViewHolder(View itemView) {
super(itemView);
textView=itemView.findViewById(R.id.text_view_recycler);
}
}
}
可以看到,RecyclerViewAdapter继承自RecyclerView.Adapter
,并通过继承RecyclerView.ViewHolder
实现了静态类ViewHolder,这是为了充分利用RecyclerView的View复用机制。
主要重写的方法有onCreateViewHolder
、onBindViewHolder
和getItemCount
,分别用于创建ViewHolder、绑定数据和返回数据总数量。
在为RecyclerView设置Adapter之前,我们先为RecyclerView设置合适的LayoutManager。LayoutManager用于管理列表项的排列方式,通过使用不同的LayoutManager,可以在不改变适配器的情况下随意改变列表排列方式,这也是RecyclerView得以解耦合的原因。示例代码如下:
LinearLayoutManager linearLayoutManager=new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);//设置为纵向排列
recyclerView.setLayoutManager(linearLayoutManager);//设置布局管理器
在本例中使用LinearLayoutManager
。这是一个线性的布局管理器,可以设置为横向或纵向排列,选择为纵向排列其实就实现了ListView的效果。
最后,再为RecyclerView设置好适配器就行了,示例代码如下:
//生成随机数据
private List<String> createDataList(){
List<String> list=new ArrayList<>();
String[] rootArray={
"Java","Android","Swift","Python","Ruby"};
for(int i=0;i<60;i++){
list.add(rootArray[i%rootArray.length]+i);
}
return list;
}
List<String> dataList=createDataList();//数据源
RecyclerViewAdapter recyclerViewAdapter=new RecyclerViewAdapter(dataList);
recyclerView.setAdapter(recyclerViewAdapter);//设置适配器
最后,总结一下RecyclerView的使用步骤:
- 准备列表项布局文件
- 实现适配器
- 为RecyclerView设置布局管理器
- 为RecyclerView设置适配器
效果截图:
监听列表项的点击事件
和ListView不同,RecyclerView并没有提供为列表项设置点击监听器的方法,因此我们需要自己去实现这一需求。
首先,在Adapter类中定义一个内部接口,并将其作为Adapter的成员变量,以及实现相应的setter方法,代码如下:
...
private ItemClickListener itemClickListener;//列表项点击监听器
//为RecyclerView设置点击监听器
public void setItemClickListener(ItemClickListener itemClickListener) {
this.itemClickListener = itemClickListener;
}
//自定义的点击监听器接口
public interface ItemClickListener{
void onItemClick(String clickItem);//单击事件
void onItemLongClick(String clickItem);//长按事件
}
...
之后,在onBindViewHolder
方法中为列表项设置点击监听器,并调用ItemClickListener
中相应的方法,代码如下:
@Override
public void onBindViewHolder(ViewHolder holder, int position){
....
//为列表项设置点击监听
if(itemClickListener!=null){
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
itemClickListener.onItemClick(itemContent);
}
});
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
itemClickListener.onItemLongClick(itemContent);
return true;
}
});
}
}
最后,只需要为RecyclerView设置相应的接口,就轻松地实现了监听列表项点击事件的需求,代码如下:
recyclerViewAdapter.setItemClickListener(new RecyclerViewAdapter.ItemClickListener() {
@Override
public void onItemClick(String clickItem) {
Toast.makeText(RecyclerViewActivity.this,"点击:"+clickItem,
Toast.LENGTH_SHORT).show();
}
@Override
public void onItemLongClick(String clickItem) {
Toast.makeText(RecyclerViewActivity.this,"长按:"+clickItem,
Toast.LENGTH_SHORT).show();
}
});
使用不同的LayoutManager
在上面的例子中,我们使用LinearLayoutManager实现了类似ListView的效果。实际上,RecyclerView一共提供了三种LayoutManger,用于实现多种布局效果。下面简单介绍一下这几种布局管理器:
- LinearLayoutManager:线性布局管理器,有横向和纵向两种布局方向,可以通过
setOrientation
方法设置布局方向。 - GridLayoutManager:网格布局管理器,可以实现类似GridView的排列效果,属于LinearLayoutManager的子类。
- StaggeredGridLayoutManager:可以实现瀑布流的布局管理器。
注意:如果要实现瀑布流式布局,要求Item的高度不同(纵向排列时),否则StaggeredGridLayoutManager的显示效果和GridLayoutManager相同。
GridLayoutManager使用示例:
GridLayoutManager gridLayoutManager=new GridLayoutManager(RecyclerViewActivity.this,3);//3列
recyclerView.setLayoutManager(gridLayoutManager);
效果截图:
StaggeredGridLayoutManager使用示例:
//垂直排列、4列
StaggeredGridLayoutManager staggeredGridLayoutManager=new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(staggeredGridLayoutManager);
效果截图:
相关方法
RecyclerView
添加Item装饰器: