RecyclerView基础用法

希望的天 等级 331 0 0

RecyclerView 是一款非常强大的 widget,它可以帮助您灵活地显示列表数据。当我开始学习 RecyclerView 的时候,我发现对于复杂的列表界面有很多资源可以参考,但是对于简单的列表展现就鲜有可参考的资源了。虽然 RecyclerView 的组成结构乍一看有些复杂,但是深入理解以后您会发现它其实非常简单明了。

本文会通过创建一个简单的 RecyclerView 实现一个列表来显示不同种类的花的名字。在实现的过程中,我也会将 RecyclerView 的每个部分揉碎了展现给大家,这样大家就可以在自己的应用中实现了。

RecyclerView 是 "何方神圣"?为什么选择它呢?

RecyclerView 是一个容器,它用于显示列表形式 (list) 或者网格形式 (grid) 的数据,比如文本或者照片。

当列表滑动的时候,实际上只有少量邻近的视图会显示在屏幕上。当视图滑出屏幕时,RecyclerView 会复用它并且填充新的数据。由于它是通过回收已有的结构而不是持续创建新的列表项,所以它可以有效提高应用的时间效率和空间效率。

RecyclerView基础用法

粉红色的方格表示屏幕上正在显示的表项,黄色的方格表示屏幕可视范围之外的表项是如何被回收并转为新的视图

为什么您需要使用 RecyclerView 呢?

  • RecyclerView 使用 ViewHolder 模式,这样做可以提高性能,因为它无需频繁调用 findViewById() 方法即可访问表项的视图;
  • RecyclerView 使用 LayoutManager,它支持纵向滑动的列表和横向滑动的列表,以及交错布局的列表和网格布局的列表。您还可以创建自定义的 LayoutManager;
  • RecyclerView 提供默认的表项动画以及自定义动画的入口。

总之,RecyclerView 兼顾了灵活性和个性化,所以它是功能强大的工具。

实现 RecyclerView

本文会为大家展示如何实现一个简单的 RecyclerView,用它来显示不同种类花的名称。下面的代码会使用 Kotlin 语言,但是 RecyclerView 也可以在 Java 语言中使用。

RecyclerView基础用法

首先在 Android Studio 里创建一个工程,并且使用 Empty Activity 模板。设置项目名称,并且选择 Kotlin 作为项目所用的语言。

RecyclerView基础用法

接下来在 app 级的 build.gradle 文件里引入 最新版本RecyclerView 依赖。

 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

// 在 https://developer.android.google.cn/jetpack/androidx/releases/recyclerview 获得最新版本号
def recyclerview_version = "1.1.0"

implementation 'androidx.recyclerview:recyclerview:$recyclerview_version 

RecyclerView 数据

RecyclerView 最重要的组成部分之一就是需要显示的数据。对于比较复杂的应用来说,数据可能是来自数据库或者来自于网络,不过这里我们简单使用字符串资源文件作为应用的数据源。

strings.xml 文件中,创建一个字符串数组来存放花的名称。

 <!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

<resources>
    <string name="app_name">RecyclerSample</string>
    <string-array name="flower_array">
        <item>Lily</item>
        <item>Poppy</item>
        <item>Sunflower</item>
        <item>Freesia</item>
        <item>Daisy</item>
        <item>Rose</item>
        <item>Daffodil</item>
        <item>Lavender</item>
        <item>Peony</item>
        <item>Lilac</item>
        <item>Dahlia</item>
        <item>Tulip</item>
        <item>Dandelion</item>
        <item>Geranium</item>
        <item>Gardenia</item>
        <item>Rhododendron</item>
        <item>Azalea</item>
    </string-array>

</resources> 

然后,创建一个类,名字为 Datasource,并且可以接收一个 Context 类型的参数。创建一个叫做 getFlowerList() 的函数,它负责返回花的名称列表。

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

class Datasource(val context: Context) {
    fun getFlowerList(): Array<String> {
        return context.resources.getStringArray(R.array.flower_array)
    }
} 

MainActivity.onCreate() 中,创建一个变量叫做 flowerList,然后将 getFlowerList() 的返回结果赋给它。

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  setContentView(R.layout.activity_main)
  val flowerList = Datasource(this).getFlowerList()
} 

RecyclerView 布局

接下来,在 activity_main 布局文件中将 TextView 替换为 RecyclerView,并且将其 layoutManager 设置为 LinearLayoutManager。使用 LinearLayoutManager 意味着未来数据将以纵向列表或者横向列表的形式显示 (默认是纵向列表)。

 <!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   xmlns:app="http://schemas.android.com/apk/res-auto">

   <androidx.recyclerview.widget.RecyclerView
       android:id="@+id/recycler_view"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       app:layoutManager="LinearLayoutManager"/>
</FrameLayout> 

表项布局

RecyclerView基础用法

上面的示意图表示一个包含数据表项的 RecyclerView。在这里,组成 RecyclerView 的表项 (Item) 里会包含花的名称。

创建一个新的布局文件,将它命名为 flower_item,它用来决定每一个表项的显示布局。本例中布局仅需要显示一个鲜花的名称,所以这里只需要 TextView

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/flower_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="32sp" />
</FrameLayout> 

拆分 Adapter 类

接下来是 RecyclerView 的重头戏了,也就是 ViewHolderAdapter 类。ViewHolder 负责存储 RecyclerView 中每一个单独的表项所需要显示的信息。RecyclerView 仅需要创建当前所显示的表项数量的 ViewHolder 外加缓存中的几个 ViewHolder 即可。随着用户滑动屏幕,ViewHolder会被回收 (使用新数据进行填充),已有的表项会在一端消失,并且在另一端显示一个新的表项。Adapter 类从数据源获得数据,并且将数据传递给正在更新其所持视图的 ViewHolder。下图显示了 RecyclerView、Adapter、ViewHolder 和数据之间的协作关系。

RecyclerView基础用法

创建 Adapter

创建一个叫做 FlowerAdapter 的类,所需显示的列表数据作为该类的参数。

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

class FlowerAdapter(val flowerList: Array<String>) {

} 

创建 ViewHolder

创建一个叫做 FlowerViewHolder 的内部类,并且它可以接收一个 itemView 作为参数。在 ViewHolder 中,创建一个变量来引用 TextView,然后将它指向表项布局里对应的视图。然后创建 bind() 函数,它用来将花的名字 (字符串) 和携带数据的 UI (flowerTextView) 关联起来。bind() 函数接收传入的字符串,并且将字符串作为 flowerTextView 的文本内容。

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

class FlowerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
  private val flowerTextView:TextView = itemView.findViewById(R.id.flower_text)
  fun bind(word: String){
    flowerTextView.text = word
  }
} 

继承 RecyclerView.Adapter

更新 FlowerAdapter 的类定义,使其继承 RecyclerView.Adapter 类,并且将 FlowerViewHolder作为参数传入。

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

class FlowerAdapter(val flowerList: Array<String>) :
    RecyclerView.Adapter<FlowerAdapter.FlowerViewHolder>() {

} 

重写 RecyclerView.Adapter 的类需要重写三个方法 onCreateViewHolder()onBindViewHolder()getItemCount()

重写 onCreateViewHolder()

ViewHolder 创建的时候会调用该方法。在该方法里进行初始化和填充 RecyclerView 中的表项视图。该视图使用前面我们创建的用于显示文本的布局。

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FlowerViewHolder {
  val view = LayoutInflater.from(parent.context)
  .inflate(R.layout.flower_item, parent, false)
  return FlowerViewHolder(view)
} 

重写 onBindViewHolder()

onBindViewHolder() 被调用的时候,会传入参数 ViewHolder 和一个位置 (position),它表示在 flowerList 中所绑定的表项的位置。该位置可以用于提取表项所需的数据,并且将数据传递给 ViewHolder 来使数据绑定到对应的 UI。

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

override fun onBindViewHolder(holder: FlowerViewHolder, position: Int) {
  holder.bind(flowerList[position])
} 

重写 getItemCount()

RecyclerView 显示一个列表,所以它需要知道列表里共有多少项。由于 flowerList 就是数据源,所以直接返回它的长度即可。

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

override fun getItemCount(): Int {
  return flowerList.size
} 

完成 Adapter 代码

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

class FlowerAdapter(val flowerList: Array<String>) :
    RecyclerView.Adapter<FlowerAdapter.FlowerViewHolder>() {

    // 描述表项视图并且将它放在 RecyclerView 中
    class FlowerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val flowerTextView: TextView = itemView.findViewById(R.id.flower_text)

        fun bind(word: String) {
            flowerTextView.text = word
        }
    }

    // 返回一个新的 ViewHolder
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FlowerViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.flower_item, parent, false)

        return FlowerViewHolder(view)
    }

    // 返回数据列表的长度
    override fun getItemCount(): Int {
        return flowerList.size
    }

    // 显示一个指定位置的数据
    override fun onBindViewHolder(holder: FlowerViewHolder, position: Int) {
        holder.bind(flowerList[position])
    }
} 

连接到 MainActivity

我们已经创建了布局、数据列表和 adapter。现在我们可以将 RecyclerView 添加到 MainActivity,并且将 Adapter 赋值给它。

定义一个变量叫做 recyclerView,然后将 activity_main 中的 RecyclerView 赋值给 recyclerView。将 FlowerAdapter 作为您 recyclerView 的 adapter。

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val flowerList = Datasource(this).getFlowerList()
        val recyclerView: RecyclerView = findViewById(R.id.recycler_view)
        recyclerView.adapter = FlowerAdapter(flowerList)
    }
} 

现在我们运行一下,然后看看它操作起来如何:

RecyclerView基础用法

收藏
评论区

相关推荐

使用 Payload 提高 RecyclerView 渲染效率
RecyclerView.Adapter 中有个带有 payloads 参数的函数,由于这个函数不是抽象函数,被很多人忽略了。该函数定义如下: public void onBindViewHolder(VH holder, int position, List<Object payloads) { onBindViewHolder(holder,
RecyclerView之ItemDecoration使用教程
译文的GitHub地址:RecyclerView之ItemDecoration由浅入深(https://link.jianshu.com?thttps://github.com/thinkSky1206/androidblog/blob/master/RecyclerView%E4%B9%8BItemDecoration%E7%94%B1%E6%B5
Android RecyclerView如何获取滑动距离
获取RecyclerView滑动的距离。 本文演示如何获取RecyclerView的滑动距离。 要实现这个功能,需要给RecyclerView添加滑动时监听RecyclerView.OnScrollListener。 recyclerView.addOnScrollListener(new RecyclerView.OnScrollListene
完美解决Android RyclerView嵌套滑动事件冲突
在Android项目开发中,为了实现需求和兼并用户体验,相信很多人都碰到滑动事件冲突的问题。在Android系统中事件分发机制是一个很重要的组成部分,由于这事件分发机制不是本文重点,故不在此多述,如果有想详细了解的可以自己搜下,网上有很多相关资料详细描述了Android事件分发机制。 一、问题场景 由于RecyclerView自身的优点,使得它已经基本
一文搞懂什么是HTTP与HTTPS
(https://blog.csdn.net/petterp/article/details/102779257)Http与Https的区别。 在最近的开发中,深感网络相关基础知识薄弱,于是趁周末好好总结一
金三银四了,掌握 JS 这 36 个概念,助你一臂之力
作者:Mahdhi Rezvi 译者:前端小智 来源:dmitripavlutin 点赞再看,微信搜索【大迁世界(https://mp.weixin.qq.com/s/sY9ufGGKfcdaAQ7KJQs3HA)】,B站关注【前端小智(https://space.bilibili.com/31089477)】这个没有大厂背景,但有着
20 张图彻底弄懂 HTTPS 的原理
前言 近年来各大公司对信息安全传输越来越重视,也逐步把网站升级到 HTTPS 了,那么大家知道 HTTPS 的原理是怎样的吗,到底是它是如何确保信息安全传输的?网上挺多介绍 HTTPS,但我发现总是或多或少有些点有些遗漏,没有讲全,今天试图由浅入深地把 HTTPS 讲明白,相信大家看完一定能掌握 HTTPS 的原理,本文大纲如下: HTTP 为什么不安全
干货|详解位图算法在Android RecyclerView中的应用
1. 前言 1.1 关于算法金庸武侠小说中的主人公在成为绝世高手之前,都会学习一门玄门内功。郭靖有了全真派的内功才能修炼九阴真经、虚竹得到了无崖子的毕生功力后,武学造诣日渐精进、张无忌苦练五年九阳神功,日后才能融合乾坤大挪移。对于程序员,算法就是小说中的内功,编程语言就是不同门派的武功。张无忌因为有九阳神功加持仅用一天就学会了阳顶天几十年都学不成的乾
RecyclerView基础用法
是一款非常强大的 widget,它可以帮助您灵活地显示列表数据。当我开始学习 RecyclerView 的时候,我发现对于复杂的列表界面有很多资源可以参考,但是对于简单的列表展现就鲜有可参考的资源了。虽然 RecyclerView 的组成结构乍一看有些复杂,但是深入理解以后您会发现它其实非常简单明了。本文会通过创建一个简单的 RecyclerView 实现一
https://cloud.tencent.com/developer/article/write/1830331
一、目标今天的目标是这个sign和appcode 二、步骤 Jadx没法上了app加了某梆的企业版,Jadx表示无能为力了。 FRIDADEXDumpDexDump出来,木有找到有效的信息。 Wallbreaker葫芦娃的Wallbreaker可以做些带壳分析,不过这个样本,用Frida的Spawn模式可以载入,Attach模式会失败。而直接用Objecti
RecyclerView更全解析之 - 基本使用和分割线解析
1.概述 昨天跟自己群里的人唠嗑的时候发现还有人在用Eclipse,我相信可能还是有很多人在用ListView,这里介绍一个已经出来的n年了的控件RecyclerView,实现ListView,GridView,瀑布流的效果。还可以轻松的实现一些复杂的功能,如QQ的拖动排序,侧滑删除等等。相关文章:                     
RecyclerView更全解析之 - 打造通用的万能Adapter
1.概述 离春节只有一个月,同时也在准备公司的节目所以每天有一段时间在练习吉他,刚刚群里有人问我什么时候开始分享仿内涵段子整个项目。算一下时间RecyclerView可能有4期左右的分享,自己又只能周末录讲解视频,所有可能会要等过完春节才能全部开始。   上一篇已经简单的讲解了一下。这一期我们来看一下怎么去打造一个万能的RecyclerView.Adap
RecyclerView更全解析之 - 打造通用的下拉刷新上拉加载
1.概述 这期我们在上一期的的基础上再去增加功能,我相信我们在真正的实践开发过程中肯定少不了下拉刷新和上拉加载。   我们需要思考一个问题上拉刷新下拉加载风格各式各样,淘宝和京东的列表刷新样式就肯定不一样,我们怎么样做到版本迭代的时候可以快速的更改样式。有时还需要显示正在加载数据或者无数据,比如筛选的时候有可能会出现没有数据的情况会显示无数据页面,怎么快
RecyclerView更全解析之 - 仿支付宝侧滑删除和拖动排序
1.概述 这是春节前的最后一篇分享技术的博客了,接下来的时间需要去完善视频讲解,至于今年都干了哪些事有什么成就吹牛的这里就不多说了,声明一下图片资源我是盗用的别人的。这是最后一期分享RecyclerView了,我们直接看这一期需要分享的效果:      这里写图片描述         视频讲解:相关文章:               
RecyclerView更全解析之 - 为它优雅的添加头部和底部
1.概述 上一期的,解决了几个坑。那么这一期我们来动态为RecyclerView去加载头部和底部,为上一期的RecyclerView列表数据添加广告轮播图,至于广告轮播大家可以看一下这一期 ,这里我就不多讲了,直接拿过来用。      视频讲解:相关文章: