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内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2021-10-08

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

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

RecyclerView使用payload实现局部刷新

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

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

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

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

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

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

Android RecyclerView详解之实现 ListView GridView瀑布流效果

 什么是RecyclerView RecyclerView 是Google推出的最新的 替代ListView.GridView的组件,RecyclerView是用来显示大量数据的容器,并通过有限数量的子View,来提高滚动时的性能. 与ListView不同,RecyclerView 不再负责布局,而是专注于布局复用.布局主要通过 LayoutManager来管理,目前提供了3种常用的布局管理: LinearLayoutManager 线性布局管理器 (ListView效果) GridLayout

javascript实现瀑布流自适应遇到的问题及解决方案

这几天看了Amy老师的用javascript实现瀑布流,我跟着把代码敲出来.发现这样写只能第一次载入时适应屏幕,以后改变窗口大小就不能做到自适应了. 于是我想到了用window.onresize来使得瀑布流函数从新加载来达到目的, 复制代码 代码如下: window.onload=function(){     //瀑布流函数     waterfall('content','box');     //模拟数据加载     var dataInt = {"data":[{"s

javascript自适应宽度的瀑布流实现思路

这样的布局并不陌生,从2011年Pinterest创立以来,中国互联网就迅速掀起了一股模仿Pinterest的热潮,国内有众多网站采用瀑布流的布局方式,例如花瓣网.美丽说等等.而事实上在中国互联网,模仿一些在国外被人看好的模式(当然,你也可以说是山寨或抄袭,呵呵!!)向来都是一个不错的idea. OK,现在进入正题.这里主要介绍瀑布流的一种实现方法:绝对定位(css)+javascript+ajax+json.简单一点如果不做滚动加载的话就是绝对定位(css)+javascript了,ajax和

JavaScript实现图片瀑布流和底部刷新

瀑布流现在基本上是图片显示网页的标配,主要是为了适配图片和文字块的大小,使显示出的效果没有那么呆板 实现这个功能首先要有html,css和js基础 首先先实现瀑布流 即下一行的图片放在上一行的凹下去的地方 基本的html代码如下 <html lang="en"> <head> <meta charset="UTF-8"> <title>瀑布流</title> <link rel="style

详解javascript实现瀑布流列式布局

本文介绍了javascript瀑布流列式布局的相关内容,分享给大家供大家参考,具体内容如下 JS原理 上面说了,列式布局简直算是完虐绝对式布局. 绝对式布局,简直就像10元/天 的搬砖工.而列式布局就是站在那看他搬砖的监工. 同样都是搬砖的,一个卖苦力,一个秀智商.简直了!!! 听了逼逼,我们来直面一下惨淡的人生. 列式布局的原理其实和绝对式布局没有太大的却别. 同样也有3个部分, 一是页面加载自适应,二是滑动加载,三是响应式布局. 分别讲解: 1.加载自适应 我们先看一下代码吧: var $

深入探秘jquery瀑布流的实现

瀑布流也应该算是流行几年了吧.首先是由Pinterest掀起的浪潮,然后国内设计如雨后春笋般,冒出很多瀑布流的例子,比如,蘑菇街,Mark之(不过最近涉黄,好像被喝茶了),还有淘宝的 "哇哦". 这些都是很棒的例子, 今天我想重新谈起瀑布流,一是想满足我自己的愿望,写一个详细的介绍(不敢自名为教程),二是,给大家一份参考,因为search很多,但是他们给的是一个插件,然后教你怎样配置,当然,也有很多其他的大神也细心的做了很多教程,比如 imooc上面 Amy 姐姐 发布的瀑布流教程,也

jQuery实现瀑布流的取巧做法分享

分析:瀑布流,做法有2种 (1)绝对定位方案:每个单元格设置为绝对定位,通过计算,分别设置 top , left 即可实现 (2)浮动方案:弄N列布局(浮动),然后图片数据,按顺序依次插入,如N为3列 ,第一张图片插入到第一列,第二张图片插入到第二列,第三张图片插入到第三列,第四张图片插入到第一列........这样循环插入(不能自适应) CSS与HTML代码: 复制代码 代码如下: body,ul,li{margin:0;margin:0;}     ul{list-style:none;}

jQuery图片瀑布流的简单实现代码

简单版的Jquery实现图片瀑布流思路,供大家参考,具体内容如下 注意:本篇文章基于知道每张图片的实际尺寸的情况下 特点:列数自适应,图片宽度固定 已知BUG: 像本案例中的刚好5张图片循环显示且只有5列的情况下会有问题,解决办法就是给予样式的时候不按顺序,而是先将图片放在top值最低的列 1.预备 1.基础html <div id="main"> <div class="img-item"><img src="images/

JS原生瀑布流效果实现

今天早起看了慕课的瀑布流,的确讲的十分详细,也十分的好,我在博客里也就只能给代码加些注释,和说一下思路.建议大家去看一下慕课的瀑布流教程,非常详细,每一个细节都讲的非常好,只要懂JS的基础代码,看起来应该不是多大问题,里面没有太难得方法,但自己写不出来还是因为思路上有问题,下面就详细说一下几个重点方法的代码,建议大家去慕课详细学习 HTML 和CSS没有太难得地方 <div id="main">//一个main包含了整个页面内容,box用来做一个外容器,img作为图片容器

Vue瀑布流插件的使用示例

我自己写的一个的Vue瀑布流插件,列数自适应,不用设置每个卡片的高度. 测试页面:Page.vue 模板页面:WaterFollow.vue 和 WFColumn.vue 在Page.vue中,修改itemW的值,设置每列的最小宽度.例如:itemW="200"(意为200px).list为数组.高度不用设置,:style="{height:item+'px'}"是我为了创造卡片高度加上去的,不加就显示卡片的原来大小. 经测试,created加载数据正常,mount