一、概述
RrcyclerView是ListView的加强版,不仅可以轻松实现和ListView同样的效果,还优化了ListView中存在的各种不同之处。
Android官方推荐我们使用RecyclerView。
二、基本用法
1.首先需要在项目的build.gradle中添加相应的依赖库:
implementation 'com.android.support:recyclerview-v7:27.1.1'
2.在layout布局中添加RecyclerView空间:activity_list_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.support.v7.widget.RecyclerView
android:id="@+id/recycle_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
3.新建Adapter适配器:FruitRecyclerAdapter.java
public class FruitRecyclerAdapter extends RecyclerView.Adapter<FruitRecyclerAdapter.ViewHolder> {
//数据源
private List<Fruit> mFruitList;
public FruitRecyclerAdapter(List<Fruit> mFruitList) {
this.mFruitList = mFruitList;
}
//自定义内部类 ViewHolder
public static class ViewHolder extends RecyclerView.ViewHolder {
ImageView fruitImage;
TextView fruitName;
Button button;
LinearLayout itemDetail;
public ViewHolder(View itemView) {
super(itemView);
fruitImage = (ImageView) itemView.findViewById(R.id.fruit_image);
fruitName = (TextView) itemView.findViewById(R.id.fruit_name);
button = (Button) itemView.findViewById(R.id.fruit_button);
itemDetail = (LinearLayout) itemView.findViewById(R.id.item_detail);
}
}
//用于创建ViewHolder实例,并加载布局
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
//对RecyclerView子项数据进行赋值
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
Fruit fruit = mFruitList.get(position);
holder.fruitImage.setImageResource(fruit.getImageId());
holder.fruitName.setText(fruit.getName());
}
//RecyclerView子项的个数
@Override
public int getItemCount() {
return mFruitList.size();
}
}
4. 新建item子布局layout:fruit_item.xml
- 新建适配器类要继承RecyclerView.Adapter<...>,继承的泛型ViewHolder需要我们自己新建内部类ViewHolder。
- 内部类ViewHolder,继承RecyclerView.ViewHolder。
- 新建构造函数,初始化数据源list。
- 因为继承了RecyclerView.Adapter,所以要重写onCreateViewHolder()、onBindViewHolder()、getItemCount()三个方法。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/item_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="@drawable/border"
android:orientation="vertical">
<ImageView
android:id="@+id/fruit_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<Button
android:id="@+id/fruit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="点击" />
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginStart="10dp" />
</LinearLayout>
5.activity对RecyclerView的处理:
recyclerView = (RecyclerView) findViewById(R.id.recycle_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
adapter = new FruitRecyclerAdapter(fruitList);
recyclerView.setAdapter(adapter);
layoutmanager用于指定RecyclerView的布局方式:
- LinearLayoutManager.VERTICAL :线性垂直
- LinearLayoutManager.HORIZONTAL:线性水平
- GridLayoutManager.VERTICAL :网格垂直
- GridLayoutManager.HORIZONTAL:网格水平
- StaggeredGridLayoutManager.VERTICAL:瀑布流
获取adapter实例,并传入数据源list。最后调用RecyclerView的setAdapter()方法。
到此RecyclerView和数据之间的关联就建立好了。
三、添加点击事件
大多数情况下,我们需要实现每个item本身或者item中的button等控件的点击事件。就需要在adapter中用到接口回调,
添加了接口回调的adapter代码如下:
public class FruitRecyclerAdapter extends RecyclerView.Adapter<FruitRecyclerAdapter.ViewHolder> {
//数据源
private List<Fruit> mFruitList;
//接口
private ClickInterface clickInterface;
public FruitRecyclerAdapter(List<Fruit> mFruitList) {
this.mFruitList = mFruitList;
}
//--------------------点击事件-------------------------------------------//
public void setOnclick(ClickInterface clickInterface) {
this.clickInterface = clickInterface;
}
//回调接口
public interface ClickInterface {
void onButtonClick(View view, int position);
void onItemClick(View view, int position);
}
//--------------------点击事件-------------------------------------------//
//自定义内部类 ViewHolder
public static class ViewHolder extends RecyclerView.ViewHolder {
ImageView fruitImage;
TextView fruitName;
Button button;
LinearLayout itemDetail;
public ViewHolder(View itemView) {
super(itemView);
fruitImage = (ImageView) itemView.findViewById(R.id.fruit_image);
fruitName = (TextView) itemView.findViewById(R.id.fruit_name);
button = (Button) itemView.findViewById(R.id.fruit_button);
itemDetail = (LinearLayout) itemView.findViewById(R.id.item_detail);
}
}
//用于创建ViewHolder实例,并加载布局
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
//对RecyclerView子项数据进行赋值
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
Fruit fruit = mFruitList.get(position);
holder.fruitImage.setImageResource(fruit.getImageId());
holder.fruitName.setText(fruit.getName());
//--------------------点击事件-------------------------------------------//
//Button点击事件
holder.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (clickInterface != null) {
clickInterface.onButtonClick(v, position);
}
}
});
//item点击事件
holder.itemDetail.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (clickInterface != null) {
clickInterface.onItemClick(v, position);
}
}
});
//--------------------点击事件-------------------------------------------//
}
//RecyclerView子项的个数
@Override
public int getItemCount() {
return mFruitList.size();
}
}
Activity代码中的点击事件处理:
recyclerView = (RecyclerView) findViewById(R.id.recycle_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
adapter = new FruitRecyclerAdapter(fruitList);
recyclerView.setAdapter(adapter);
//添加点击事件
recyclerView.post(new Runnable() {
@Override
public void run() {
adapter.setOnclick(new FruitRecyclerAdapter.ClickInterface() {
@Override
public void onButtonClick(View view, int position) {
Toast.makeText(view.getContext(), "Click Button - position: " + position + " name: " + fruitList.get(position).getName(), Toast.LENGTH_SHORT).show();
}
@Override
public void onItemClick(View view, int position) {
Toast.makeText(view.getContext(), "Click Item Detail - position: " + position + " name: " + fruitList.get(position).getName(), Toast.LENGTH_SHORT).show();
}
});
}
});
这里实现了item和button的两个点击事件。
END.