1 RecyclerView 简介
RecyclerView是Google官方提供的任何基于适配器显示的视图,可以实现普通列表(ListView),网格列表(GridView),瀑布流,以及各种自定义形式的多容器布局
RecyclerView样式与适配器等解耦:RecyclerView提供了插拔式体验,实现的Adapter适配器与显示样式设置高度解耦,在不改变Adapter适配器的前提下:
- 通过设置不同的
LayoutManager,就可以实现不同的布局展示样式 - 通过设置不同的
ItemDecoration,可以实现不同的间隔样式 - 通过设置不同的
ItemAnimator,可以实现不同的添加删除动画
例如:设置不同的LayoutManager,就可以实现不同的布局展示样式
- 设置
LinearLayoutManager布局管理器,RecyclerView展示的就是横向/纵向的列表 - 设置
GridLayoutManager布局管理器,RecyclerView展示的就是网格布局 - 设置
StaggeredGridLayoutManager布局管理器,RecyclerView展示的就是瀑布流样式的布局
1.1 RecyclerView 特点
- 功能强大:实现列表、网格、瀑布流、自定义容器等功能
- 垃圾回收机制:
RecyclerView的内部实现了回收机制,无需我们考虑View的复用情况 ViewHolder规范:RecyclerView避免了ListView中自定义ViewHolder,给出了相应的规范- 取消了
onItemClick等点击事件,需要自己手动去写
1.2 RecyclerView 涉及到的类
RecyclerView使用必须有的关键类:RecyclerView.ViewHolder、RecyclerView.Adapter、LayoutManager
RecyclerView.ViewHolder:用于定义RecyclerView中每个独立元素的显示的组件,创建时不关联数据,创建后会在RecyclerView.Adapter适配器的onBindViewHolder方法中为其关联数据RecyclerView.Adapter:主要作用是创建RecyclerView.ViewHolder,并为其绑定数据LayoutManager:布局管理器主要作用是负责排列各个元素组件,可以使用系统提供的线性布局管理器LinearLayoutManager,网格布局管理器GridLayoutManager,瀑布流布局管理器StaggeredGridLayoutManager,也可以自定义实现各种奇形怪状的布局管理器,如自定义圆形的布局管理器
设置类:
ItemDecoration:用于设置每个item的间隔样式ItemAnimator:用于设置item的动画效果,如添加动画、删除动画等
2 RecyclerView 的基本用法
在build.gradle的dependencies中添加RecyclerView的依赖库
dependencies {
implementation "androidx.recyclerview:recyclerview:1.2.1"
// For control over item selection of both touch and mouse driven selection
implementation "androidx.recyclerview:recyclerview-selection:1.1.0"
}
在布局文件中使用RecyclerView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.RecyclerViewActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
根据需要定义RecyclerView每行所实现的xml布局(item布局)。my_item_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/img_ico"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_gravity="center"/>
<TextView
android:id="@+id/text_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="50dp"/>
</LinearLayout>
自定义适配器MyAdapterRecyclerView.java
public class MyAdapterRecyclerView extends RecyclerView.Adapter<MyAdapterRecyclerView.MyViewHolder> {
private LayoutInflater mInflater;
private List<ItemData> mDataItemLists;
private RecyclerViewItemClick mRecyclerViewItemClick;
public MyAdapterRecyclerView(Context context, List<ItemData> itemDataList) {
mInflater = LayoutInflater.from(context);
this.mDataItemLists = itemDataList;
}
/**
* 创建Item视图,并返回相应的ViewHolder
* @param parent
* @param viewType
* @return
*/
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.my_list_view, null);
return new MyViewHolder(view);
}
/**
* 绑定数据到正确的Item视图上
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.imageView.setImageResource(mDataItemLists.get(position).getImg());
holder.textView.setText(mDataItemLists.get(position).getName());
if (mRecyclerViewItemClick != null) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mRecyclerViewItemClick.onItemClick(position);
}
});
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
mRecyclerViewItemClick.onItemLongClick(position);
return false;
}
});
}
}
/**
* 返回Item数量
* @return
*/
@Override
public int getItemCount() {
return mDataItemLists.size();
}
/**
* 绑定传进来的点击监听器
* @param recyclerViewItemClick
*/
public void setRecyclerViewItemClick(RecyclerViewItemClick recyclerViewItemClick){
this.mRecyclerViewItemClick = recyclerViewItemClick;
}
}
定义ViewHolder
/**
* 定义ViewHolder
*/
public static class MyViewHolder extends RecyclerView.ViewHolder {
public ImageView imageView;
public TextView textView;
public MyViewHolder(View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.img_ico);
textView = itemView.findViewById(R.id.text_name);
}
}
item点击事件接口
public interface RecyclerViewItemClick{
/**
* 点击事件
* @param position
*/
void onItemClick(int position);
/**
* 长按事件
* @param position
*/
void onItemLongClick(int position);
}
使用RecyclerView
- 定义一个HashMap构成的列表,将数据以键值对的方式存放在里面
- 构造Adapter对象,设置适配器
- 将RecyclerView绑定到Adapter上
public class RecyclerViewActivity extends AppCompatActivity implements MyAdapterRecyclerView.RecyclerViewItemClick {
private List<ItemData> mItemDataList;
private RecyclerView mRecyclerView;
private MyAdapterRecyclerView mMyAdapter;
private final String[] names = {"深圳", "上海", "西安", "杭州", "深圳", "上海", "西安", "杭州", "深圳", "上海", "西安", "杭州",
"深圳", "上海", "西安", "杭州", "深圳", "上海", "西安", "杭州", "深圳", "上海", "西安", "杭州"};
private final int[] imgs = {R.drawable.person1,R.drawable.person2,R.drawable.person1,R.drawable.person2,R.drawable.person1, R.drawable.person2,
R.drawable.person1,R.drawable.person2,R.drawable.person1,R.drawable.person2,R.drawable.person1,R.drawable.person2,
R.drawable.person1,R.drawable.person2,R.drawable.person1,R.drawable.person2,R.drawable.person1, R.drawable.person2,
R.drawable.person1,R.drawable.person2,R.drawable.person1,R.drawable.person2,R.drawable.person1,R.drawable.person2};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler_view);
initItemData();
initView();
}
private void initItemData() {
mItemDataList = new ArrayList<ItemData>();
for (int i = 0; i < names.length; i++) {
ItemData itemData = new ItemData();
itemData.setImg(imgs[i]);
itemData.setName(names[i]);
mItemDataList.add(itemData);
}
}
private void initView() {
mRecyclerView = findViewById(R.id.recycler_view);
//使用线性布局
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
mMyAdapter = new MyAdapterRecyclerView(this ,mItemDataList);
mMyAdapter.setRecyclerViewItemClick(this);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(mMyAdapter);
}
/**
* 实现 MyAdapterRecyclerView.RecyclerViewItemClick 中的接口,实现点击事件
* @param position
*/
@Override
public void onItemClick(int position) {
Toast.makeText(this, "点击事件,第 "+ position + " 个ItemView", Toast.LENGTH_SHORT).show();
}
@Override
public void onItemLongClick(int position) {
Toast.makeText(this, "长按事件,第 "+ position + " 个ItemView", Toast.LENGTH_SHORT).show();
}
}
效果图