目录
4.6 更强大的滚动控件:RecyclerView
ListView 由于强大的功能,在过去的 Android 开发当中可以说是贡献卓越,直到今天仍然还有不计其数的程序在使用 ListView 。不过 ListView 并不是完美无缺的,比如如果不使用一些技巧 来提升它的运行效率,那么 ListView 的性能就会非常差。还有,ListView 的扩展性也不够好, 它只能实现数据纵向滚动的效果,如果我们想实现横向滚动的话,ListView 是做不到的。
为此,Android 提供了一个更强大的滚动控件——RecyclerView 。它可以说是一个增强版的 ListView ,不仅可以轻松实现和 ListView 同样的效果,还优化了 ListView 存在的各种不足之处。目前 Android 官方更加推荐使用 RecyclerView ,未来也会有更多的程序逐渐从 ListView 转向RecyclerView ,那么本节我们就来详细讲解一下 RecyclerView 的用法。
首先新建一个 RecyclerViewTest 项目,并让 Android Studio 自动帮我们创建好 Activity 。
4.6.1 RecyclerView 的基本用法
和之前我们所学的所有控件不同,RecyclerView 属于新增控件,那么怎样才能让新增的控件在所有 Android 系统版本上都能使用呢?为此,Google 将 RecyclerView 控件定义在了 AndroidX 当中,我们只需要在项目的 build.gradle 中添加 RecyclerView 库的依赖,就能保证在所有 Android 系统版本上都可以使用 RecyclerView 控件了。
打开 app/build.gradle 文件,在 dependencies 闭包中添加如下内容:
dependencies {
// RecyclerView
implementation("androidx.recyclerview:recyclerview:1.2.1")
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
上述代码就表示将 RecyclerView 库引入我们的项目当中,其中除了版本号部分可能会变化,其他部分是固定不变的。那么可能你会好奇,我怎么知道每个库现在最新的版本号是多少呢?这 里告诉你一个小窍门,当你不能确定最新的版本号是多少的时候,可以就像上述代码一样填入 1.0.0 ,当有更新的库版本时,Android Studio 会主动提醒你,并告诉你最新的版本号是多少, 如图4.32 所示。
![](https://i-blog.csdnimg.cn/blog_migrate/0fcc41a7521c853f37b9b5fdb1f30956.png)
另外,每当修改了任何 gradle 文件,Android Studio 都弹出一个如 图4.33 所示的提示。
![](https://i-blog.csdnimg.cn/blog_migrate/900114e2cbfc8eb0707a84e2628cd314.png)
这个提示告诉我们,gradle 文件自上次同步之后又发生了变化,需要再次同步才能使项目正常工作。这里只需要点击 “Sync Now” 就可以了,然后 gradle 会开始进行同步,把我们新添加的 RecyclerView 库引入项目当中。
接下来修改 activity_main.xml 中的代码,如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
在布局中加入 RecyclerView 控件也是非常简单的,先为 RecyclerView 指定一个id,然后将宽度和高度都设置为 match_parent,这样 RecyclerView 就占满了整个布局的空间。需要注意的 是,由于 RecyclerView 并不是内置在系统 SDK 当中的,所以需要把完整的包路径写出来。
这里我们想要使用 RecyclerView 来实现和 ListView 相同的效果,因此就需要准备一份同样的水果图片。简单起见,我们就直接从 ListViewTest 项目中把图片复制过来,另外顺便将 Fruit 类和fruit_item.xml 也复制过来,省得将同样的代码再写一遍。
接下来需要为 RecyclerView 准备一个适配器,新建 FruitAdapter 类,让这个适配器继承自 RecyclerView.Adapter,并将泛型指定为 FruitAdapter.ViewHolder。其中, ViewHolder 是我们在 FruitAdapter 中定义的一个内部类,代码如下所示:
class FruitAdapter(private val fruitList: List<Fruit>) :
RecyclerView.Adapter<FruitAdapter.ViewHolder>(){
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view){
val fruitImage:ImageView = view.findViewById(R.id.fruitImage)
val fruitName:TextView = view.findViewById(R.id.fruitName)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):