Android强大的控件——RecylerView
RecyclerView简介
ListView由于其强大的功能,在过去的Android开发当中可以说是贡献卓越。但ListView运行时可能不太流畅,要进行相应的优化,但这种优化很大程度上取决于开发者的技巧,这对于像我这种普通开发者而言是一种挑战。而且ListView不支持水平滚动,使用起来缺乏一定的灵活性。所以,Android提供了RecyclerView来代替ListView。
RecyclerView封装了ViewHolder的回收复用。提供了一种插拔式的体验,高度的解耦,异常的灵活,针对一个Item的显示RecyclerView专门抽取了相应的类,来控制Item的显示,使其的扩展性非常强。RecyclerView有横向、竖向和瀑布流布局
基本使用
当然,RecyclerView属于新增的控件,想要使用RecyclerView,首先需要在项目的build.gradle中添加相应的依赖库才行。
注意,从版本3.2.190205开始,support库已经改为Androidx库,所以RecyclerView依赖库不再是:
compile 'com.android.support.recyclerview-v7:27.2.1'
而是:
implementation 'androidx.recyclerview:recyclerview:1.0.0'
添加完后要记得点击一下Sync Now同步一下。
创建适配器
创建适配器有下面三个步骤:
- 创建Adapter:新建一个类,让这个适配器继承RecyclerView.Adapter,并将泛型指定为CdAdapter.ViewHolder。(CdAdapter是新建类类名)
- 创建ViewHolder:在Cddapter中定义的一个内部类,继承RecyclerView.ViewHolder。记为ViewHolder。
- 在FruitAdapter中实现三个方法:
1.onCreateViewHolder(ViewGroup parent, int viewType)
该方法用于创建ViewHolder实例,并把加载出来的布局传入到构造函数当中,最后将Viewholder的实例返回
2.onBindViewHolder(FruitAdapter.ViewHolder holder, int position)
该方法是用于对RecyclerView列表项的数据进行赋值的,每次组件重新显示出来时都会重新执行该方法。
3.getItemCount()
该方法非常简单了,它用于告诉RecyclerView一共有多少个 子项,直接返回数据源的长度即可。
为了方便使用,我们先新建一个实体类,作为适配器的适配类型。新建类Cd,代码如下:
public class Cd {
private String name;
private int imageId;
public Cd(String name, int imageId) {
this.name = name;
this.imageId =imageId;
}
public String getName() {
return name;
}
public int getImageId() {
return imageId;
}
}
Cd类只有两个字段,name表示专辑名字,imageId表示专辑对应的封面资源ID
布局
接下来修改activity_main.xml中的代码,这里需要注意的是,由于RecyclerView不是内置于系统SDK,所有我们在用的时候需要把完整的包名写出来。代码如下:
<?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">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
这里的布局文件非常简单,只是添加一个RecyclerView占满屏幕并且设置一个id即可。
接下来为RecyclerView的子项指定一个自定义的布局,在layout目录下新建cd_item.xml,ImageView用于显示专辑封面,TextVIew用于显示专辑名称。代码如下:
<?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="wrap_content">
<ImageView
android:id="@+id/cd_image"
android:layout_width="80dp"
android:layout_height="80dp"/>
<TextView
android:id="@+id/cd_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"/>
</LinearLayout>
ok,布局就这样了,其实没有多么复杂,接下来看看适配器。
适配器
接着为RecyclerView准备一个适配器,新建一个CdAdapter类,让这个适配器继承子RecyclerView.Adapter,并将泛型指定为Cd.ViewHolder。ViewHolder是在CdAdapter定义的一个内部类。代码如下:
public class CdAdapter extends RecyclerView.Adapter<CdAdapter.ViewHolder> {
private List<Cd> mCdList;
static class ViewHolder extends RecyclerView.ViewHolder {
ImageView cdImage;
TextView cdName;
public ViewHolder(View view) {
super(view);
cdImage = view.findViewById(R.id.cd_image);
cdName = view.findViewById(R.id.cd_name);
}
}
public CdAdapter(List<Cd> cdList) {
mCdList = cdList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cd_item,
parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Cd cd = mCdList.get(position);
holder.cdImage.setImageResource(cd.getImageId());
holder.cdName.setText(cd.getName());
}
@Override
public int getItemCount() {
return mCdList.size();
}
}
设配器也准备好了,最后就是MainAvtivity了。
MainActivity
在MainActivity中我们使用一个initCd方法初始化所有专辑数据。在onCreate()方法中获取到RecyclerView实例,创建一个LinearLayoutManager对象,并将它设置到RecyclerView中。LayoutManager用于指定RecyclerView的布局方式,这里使用的LinearLayoutManager是线性布局。接下来创建CdAdapter实例,并将专辑数据传入到CdAdapter的构造函数当中去,最后一步就是调用RecyclerView的setAdapter()方法完成适配器设置。
MainActivity代码如下:
public class MainActivity extends AppCompatActivity {
private List<Cd> cdList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initCd();
RecyclerView recyclerView = findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
CdAdapter adapter = new CdAdapter(cdList);
recyclerView.setAdapter(adapter);
}
private void initCd() {
for (int i = 0; i < 3; i++) {
Cd cd1 = new Cd("Jay", R.drawable.cd1);
cdList.add(cd1);
Cd cd2 = new Cd("范特西", R.drawable.cd2);
cdList.add(cd2);
Cd cd3 = new Cd("八度空间", R.drawable.cd3);
cdList.add(cd3);
Cd cd4 = new Cd("叶惠美", R.drawable.cd4);
cdList.add(cd4);
Cd cd5 = new Cd("七里香", R.drawable.cd5);
cdList.add(cd5);
Cd cd6 = new Cd("十一月的萧邦", R.drawable.cd6);
cdList.add(cd6);
Cd cd7 = new Cd("依然范特西", R.drawable.cd7);
cdList.add(cd7);
Cd cd8 = new Cd("我很忙", R.drawable.cd8);
cdList.add(cd8);
Cd cd9 = new Cd("摩杰座", R.drawable.cd9);
cdList.add(cd9);
Cd cd10 = new Cd("跨时代", R.drawable.cd10);
cdList.add(cd10);
Cd cd11 = new Cd("惊叹号", R.drawable.cd11);
cdList.add(cd11);
Cd cd12 = new Cd("十二新作", R.drawable.cd12);
cdList.add(cd12);
Cd cd13 = new Cd("哎哟,不错哦", R.drawable.cd13);
cdList.add(cd13);
Cd cd14 = new Cd("周杰伦的床边故事", R.drawable.cd14);
cdList.add(cd14);
}
}
}
为了能有好的效果,我们将子项循环添加三次,以布满整个屏幕,效果如下:
参考《第一行代码》