《第一行代码》——书中整理摘录
首先,若要使用RecyclerView布局,我们需要为其添加依赖库。
//noinspection GradleCompatible
implementation 'com.android.support:recyclerview-v7:28.0.0'
使用:宽度和高度占满整个布局空间,并为其指定id即可。
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/my_recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
为RecyclerView准备一个适配器,该适配器继承RecyclerView.Adapter
,并将泛型指定为自定义的内部类,在书中的示例为FruitAdapter.ViewHolder
。具体代码如下所示,代码具体含义见注释。
总体而言,该适配器需要获取布局中的实例并进行绑定,使其能够呈现到屏幕中来。一个自定义的holder“hold”住了整个实例,通过它进行具体信息的设置。
public class FruitAdapter extends RecyclerView.Adapter {
@NonNull
@Override
private List<Fruit> mFruitList;
//此处创建了一个内部类,该类继承RecyclerView.viewHolder,通过这个自定义的内部类,可以获取布局中的实例。此处的布局是具体项目信息的实例了,如一组水果的消息包含的图片和名字。
static class ViewHolder extends RecyclerView.ViewHolder{
ImageView fruitImage;
TextView fruitName;
public ViewHolder(View view){//这里传入的view通常是RecyclerView子项的最外层布局
super(view);
fruitImage = view.findViewById(R.id.fruit_iamge);//获取布局实例
fruitName = view.findViewById(R.id.fruit_name);
}
}
//适配器类的构造方法
public FruitAdapter(List<Fruit> fruitList){
this.mFruitList = fruitList;
}
//由于继承关系必须重写下列三个方法
//用于创建ViewHloder实例,加载fruit_item布局并作为实例返回。此时的fruit_item是具体项目信息的整个的布局,如上文提到的图片和名字合在一起的布局
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,parent,false);
ViewHolder holder = new ViewHolder(view);//实例化自定义的holder
return holder;
}
//对RecyclerView子项的数进行赋值,在每个子项被滚动到屏幕内的时候执行。根据position参数定位,利用viewholder对其进行赋值。
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, 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();
}
}
使用方法:在主函数中使用方法如下。
//此处的布局文件是最外层的recyclerview布局,建立联系
RecyclerView recyclerView = findViewById(R.id.recycler_view);
//为这个recyclerview设定线性布局
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
//自定义适配器实例化并为这个recyclerview添加自定义的适配器
FruitAdapter adapter = new FruitAdapter(fruitList);
recyclerView.setAdapter(adapter);
观察得知,RecyclerView的布局交由LayoutManager
管理,因此改变其布局模式十分容易。listview
无法实现的横向滑动在此只需要添加一句layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
即可。如果想实现瀑布流,则只需要将layoutManager
换成
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
其中,3表示列数,VERTICAL表示纵向排列。
下面为RecyclerView增加监听事件。RecyclerView可以做到具体任意控件或布局,这是其优异的地方。因此对刚才FruitAdapter
类进行一定的修改。增加了fruitView
类保存最外层的view布局,因此最外层也可以被监听了。具体监听修改的部分如下所示。
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,parent,false);
final ViewHolder holder = new ViewHolder(view);//实例化自定义的holder
holder.fruitView.setOnClickListener(new View.OnClickListener(){
@override
public void onClick(View v){
int position = holder.getAdapterPosition();
Fruit fruit = mFruitList.get(position);
Toast.makeText(v.getContext(),...).show();
}
});
holder.fruitImage.setOnClickListener(new View.OnClickListener(){
@override
public void onClick(View v){
int position = holder.getAdapterPosition();
Fruit fruit = mFruitList.get(position);
Toast.makeText(v.getContext(),...).show();
}
});
return holder;
}