Android入门教程之RecyclerView的具体使用详解

目录
  • RecyclerView 的基本用法
  • 横向滚动
  • RecyclerView 点击事件

RecyclerView 的基本用法

和我们之前学习的控件不一样,RecyclerView 属于新增控件,所以我们需要在项目的 build.gradle 中添加 RecyclerView 库的依赖,才能使用该控件

dependencies {

    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.2.0'
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'com.google.android.material:material:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.recyclerview:recyclerview:1.1.0'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

修改 activity_main.xml 中的代码,如下所示

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

这里我们想要使用 RecyclerView 实现了 ListView 一样的效果,准备一个适配器,新建 FruitAdapter 类,让这个适配器继承 RecyclerView.Adapter,并将泛型指定为 FruitAdapter.ViewHolder,其中 ViewHolder 是我们在 FruitAdapter 中定义的一个内部类

class FruitAdapter(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): FruitAdapter.ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.fruit_item, parent, false)
        return ViewHolder(view)
    }

    override fun getItemCount() = fruitList.size

    override fun onBindViewHolder(holder: FruitAdapter.ViewHolder, position: Int) {
        val fruit = fruitList[position]
        holder.fruitImage.setImageResource(fruit.imageId)
        holder.fruitName.text = fruit.name
    }
}

首先,我们定义一个内部类 ViewHolder,继承自 RecyclerView.ViewHolder,然后 ViewHolder 的主构造函数中传入一个 View 参数,这个参数通常是 RecyclerView 子项的最外层布局,然后我们就可以通过 findViewById() 方法来获取布局中的 ImageView 和 TextView 实例了

FruitAdapter 继承自 RecyclerView.Adapter,那么就必须重写 onCreateViewHolder()、onBindViewHolder()、getItemCount() 这三个方法:

  • onCreateViewHolder() 方法用于创建 ViewHolder 实例
  • onBindViewHolder() 方法用于对 RecyclerView 子项的数据进行赋值
  • getItemCount() 方法告诉 RecyclerView 一共有多少个子项,直接返回数据源的长度

修改 MainActivity 中的代码,开始使用 RecyclerView

class MainActivity : AppCompatActivity() {

    private val fruitList = ArrayList<Fruit>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initFruits()
        val layoutManager = LinearLayoutManager(this)
        recyclerView.layoutManager = layoutManager
        val adapter = FruitAdapter(fruitList)
        recyclerView.adapter = adapter
    }

    private fun initFruits() {
        repeat(2) {
            fruitList.add(Fruit("Apple", R.drawable.apple_pic))
            fruitList.add(Fruit("Banana", R.drawable.banana_pic))
            fruitList.add(Fruit("Orange", R.drawable.orange_pic))
            fruitList.add(Fruit("Watermelon", R.drawable.watermelon_pic))
            fruitList.add(Fruit("Pear", R.drawable.pear_pic))
            fruitList.add(Fruit("Grape", R.drawable.grape_pic))
            fruitList.add(Fruit("Pineapple", R.drawable.pineapple_pic))
            fruitList.add(Fruit("Strawberry", R.drawable.strawberry_pic))
            fruitList.add(Fruit("Cherry", R.drawable.cherry_pic))
            fruitList.add(Fruit("Mango", R.drawable.mango_pic))
        }
    }
}

在 onCreate() 方法中先创建一个 LinearLayoutManager 对象,并设置到 RecyclerView 中,用于指定 RecyclerView 的布局方式。然后再创建 FruitAdapter 的实例,调用 RecyclerView 的 setAdapter() 方法完成适配器设置

横向滚动

如果我们要实现横向滚动的话,要先对 fruit_item 的布局进行修改,把里面的元素改成垂直排列

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="80dp"
    android:layout_height="wrap_content"
    tools:ignore="UseCompoundDrawables">

    <ImageView
        android:id="@+id/fruitImage"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp"
        tools:ignore="ContentDescription,RtlHardcoded" />

    <TextView
        android:id="@+id/fruitName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp"
        tools:ignore="RtlHardcoded" />

</LinearLayout>

接下来修改 MainActivity 中的代码

class MainActivity : AppCompatActivity() {

    private val fruitList = ArrayList<Fruit>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initFruits()
        val layoutManager = LinearLayoutManager(this)
        layoutManager.orientation = LinearLayoutManager.HORIZONTAL
        recyclerView.layoutManager = layoutManager
        val adapter = FruitAdapter(fruitList)
        recyclerView.adapter = adapter
    }

	...
}

除了横向滚动,RecyclerView 还能实现瀑布流和网格布局

RecyclerView 点击事件

不同于 ListView,RecyclerView 并没有提供类似于 setOnItemClickListener() 这样的注册监听器方法,而是需要我们自己给子项具体的 View 注册点击事件

修改 FruitAdapter 中的代码

class FruitAdapter(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): FruitAdapter.ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.fruit_item, parent, false)
        val viewHolder = ViewHolder(view)
        viewHolder.itemView.setOnClickListener {
            val position = viewHolder.adapterPosition
            Log.d("FruitAdapter", position.toString())
            val fruit = fruitList[position]
            Toast.makeText(parent.context, "you clicked view ${fruit.name}", Toast.LENGTH_SHORT).show()
        }
        viewHolder.fruitImage.setOnClickListener {
            val position = viewHolder.adapterPosition
            Log.d("FruitAdapter", position.toString())
            val fruit = fruitList[position]
            Toast.makeText(parent.context, "you clicked image ${fruit.name}", Toast.LENGTH_SHORT).show()
        }
        return viewHolder
    }

    override fun getItemCount() = fruitList.size

    override fun onBindViewHolder(holder: FruitAdapter.ViewHolder, position: Int) {
        val fruit = fruitList[position]
        holder.fruitImage.setImageResource(fruit.imageId)
        holder.fruitName.text = fruit.name
    }
}

到此这篇关于Android入门教程之RecyclerView的具体使用详解的文章就介绍到这了,更多相关Android RecyclerView内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 一文搞懂Android RecyclerView点击展开、折叠效果的实现代码

    RecyclerView是什么 RecycleView是Android5.0后谷歌推出的一个用于在有限的窗口中展示大量数据集的控件,位于support-v7包中.它可以实现与ListView和GridView一样的效果,提供了一种插拔式的体验,高度的解耦,异常的灵活,只需设置其提供的不同的LayoutManager,ItemAnimator和ItemDecoration,就能实现不同的效果. RecyclerView的优点 1.支持局部刷新.    2.可以自定义item增删时的动画.    3

  • RecyclerView使用payload实现局部刷新

    本文实例为大家分享了RecyclerView使用payload实现局部刷新的具体代码,供大家参考,具体内容如下 列表局部刷新: 01.notifyDataSetChanged() 刷新全部可见的item 02.notifyItemChanged(int position) 更新列表position位置上的数据可以调用 03.notifyItemInserted(int position) 列表position位置添加一条数据时可以调用,伴有动画效果 04.notifyItemRemoved(in

  • Android recyclerview实现纵向虚线时间轴的示例代码

    效果图 代码 package com.jh.timelinedemo; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.DashPathEffect; import android.graphics.Paint; import android.util.AttributeSet; import

  • Android自定义RecyclerView Item头部悬浮吸顶

    本文实例为大家分享了Android自定义RecyclerView Item头部悬浮吸顶的具体代码,供大家参考,具体内容如下 概述 1.自定义了一个FrameLayout,引入条目的头部布局加入到自定义FrameLayout中. 2.将RecyclerView加入FrameLayout 3.条目头部View的Alpha动画以及设置透明和不透明这个时机大多是通过打log来确定的,硬推理还是有些难. 4.当屏幕显示区域的第二条Item距离控件顶端的距离小于条目头部View高度时,就开始移动条目头部Vi

  • 使用RecyclerView实现瀑布流高度自适应

    使用RecyclerView实现的瀑布流高度自适应,供大家参考,具体内容如下 背景:使用时在RecyclerView外嵌套了自定义的ScrollView,需要让RecyclerView高度自适应,由于是瀑布流格式网上找了好多方法都无法实现或是动态计算的高度不准确.估计大家都知道recyclerview 内容的高度不是 recyclerview 控制的而是由LayoutManager 来设置的.下面我来说下我的解决方案吧: 布局中的使用 <android.support.v7.widget.Rec

  • Android入门教程之RecyclerView的具体使用详解

    目录 RecyclerView 的基本用法 横向滚动 RecyclerView 点击事件 RecyclerView 的基本用法 和我们之前学习的控件不一样,RecyclerView 属于新增控件,所以我们需要在项目的 build.gradle 中添加 RecyclerView 库的依赖,才能使用该控件 dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementa

  • Android入门教程之ListView的具体使用详解

    目录 ListView 的简单用法 定制 ListView 的界面 提升 ListView 的运行效率 ListView 的点击事件 ListView 的简单用法 在布局中加入 ListView 控件还算简单,先为 ListView 指定一个 id,然后将宽度和高度都设置为 match_parent,这样 ListView 就占满了整个布局的空间 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&

  • Android入门教程之Fragment的具体使用详解

    目录 Fragment 的简单用法 动态加载 Fragment Fragment 实现返回栈 Fragment 和 Activity 之间的交互 Fragment 生命周期 Fragment 的简单用法 Fragment 是一种可以嵌入在 Activity 当中的 UI 片段,它能让程序更加合理和充分地利用大屏幕的空间,因此在平板上应用非常广泛 在一个 Activity 中添加两个 Fragment,并让两个 Fragment 平分 Activity 的空间,首先新建一个左侧 Fragment

  • AngularJS入门教程之REST和定制服务详解

    在这一步中,我们会改进我们APP获取数据的方式. 请重置工作目录: git checkout -f step-11 对我们应用所做的最后一个改进就是定义一个代表RESTful客户端的定制服务.有了这个客户端我们可以用一种更简单的方式来发送XHR请求,而不用去关心更底层的$http服务(API.HTTP方法和URL). 步骤9和步骤10之间最重要的不同在下面列出.你可以在GitHub里看到完整的差别. 模板 定制的服务被定义在app/js/services,所以我们需要在布局模板中引入这个文件.另

  • AngularJS入门教程之XHR和依赖注入详解

    到现在为止,我们使用是硬编码的三条手机记录数据集.现在我们使用AngularJS一个内置服务$http来获取一个更大的手机记录数据集.我们将使用AngularJS的依赖注入(dependency injection (DI))功能来为PhoneListCtrl控制器提供这个AngularJS服务. 请重置工作目录: git checkout -f step-5 刷新浏览器,你现在应该能看到一个20部手机的列表. 步骤4和步骤5之间最重要的不同在下面列出.你可以在GitHub里看到完整的差别. 数

  • ES6入门教程之let和const命令详解

    前言 在javascript中,我们都知道使用var来声明变量.javascript是函数级作用域,函数内可以访问函数外的变量,函数外不能访问函数内的变量. 函数级作用域会导致一些问题就是某些代码块内的变量会在全局范围内有效,这我们是非常熟悉的: for (var i = 0; i < 10; i++) { console.log(i); // 0,1,2...,9 } console.log(i); //10 if(true){ var s = 20; } console.log(s); //

  • Zend Framework教程之Application和Bootstrap用法详解

    本文实例讲述了Zend Framework教程之Application和Bootstrap用法.分享给大家供大家参考,具体如下: 在一个MVC应用程序中,我们需要初始化建立数据库链接,配置视图和视图助手,配置布局,注册相关插件,注册action 助手等等,这些配置和准备工作我们都需要一一完成.有时候可能有一些初始化操作需要,但是在有些情况下这些初始化可能不需要.通过Zend_Application不仅仅可以完成这些操作,而且可以让这些配置和初始化工作更统一有序,重用性更高. Zend_Appli

  • Java并发教程之Callable和Future接口详解

    刚把Thread 的知识理了一遍. Runnable是一个接口,而Thread是Runnable的一个实现类. 所以也就有了之前创建线程的两种方法 继承Thread 实现Runnable 我们看一下新建线程的方法: 都是得传入一个Runnable对象(这句话很关键) 所以传入一个Runnble和Thread对象都行. 现在引入创建线程的第三种方法:Callable 为了实现 Runnable,需要实现不返回任何内容的 run()方法,而对于 Callable,需要实现在完成时返回结果的 call

  • Android入门教程之ListView的应用示例

    本文实例讲述了Android ListView的简单应用.分享给大家供大家参考,具体如下: 我们今天要讲的内容是Android中ListView中的实现.一共分为四个步骤,我将一一讲解: Step one:创建一个新的Android工程,命名为ListViewDemo. Step two:找到ListViewDemo.Java,把我们习惯的继承Activity,改成ListActivity,如下: public class ListViewDemo extends ListActivity St

  • Android入门教程之Picasso框架

    一.简介: Picasso是Square公司开源的一个Android图形缓存库.可以实现图片下载和缓存功能. 二.Picasso的特性 Picasso是一个Android图片加载缓存框架,它具有如下特性: 1.支持任务优先级,会优先加载"优先级"较高的图片. 2.带有统计监控功能,可以统计缓存命中率,实时监控已使用的内存等等. 3.能够根据当前网络状态自动调整并发线程数. 4.支持图片的延迟加载. 5.本身不具有本地缓存,而是使用的OkHttp实现. Picasso除了使用上比较简单.

随机推荐