Android强大的控件——RecyclerView

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同步一下。

创建适配器

创建适配器有下面三个步骤:

  1. 创建Adapter:新建一个类,让这个适配器继承RecyclerView.Adapter,并将泛型指定为CdAdapter.ViewHolder。(CdAdapter是新建类类名)
  2. 创建ViewHolder:在Cddapter中定义的一个内部类,继承RecyclerView.ViewHolder。记为ViewHolder。
  3. 在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);
        }
    }
}

为了能有好的效果,我们将子项循环添加三次,以布满整个屏幕,效果如下:
在这里插入图片描述

参考《第一行代码》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值