当前位置: 首页 > news >正文

RecyclerView进阶知识讲解

在 Android 开发中,RecyclerView 是一种高效的列表和网格布局控件,用于显示大规模数据。尽管基本使用方法简单,但深入理解并掌握其高级进阶用法能大幅提升用户体验和应用性能。下面,我将从布局管理、动画和手势、自定义缓存、优化性能等方面系统介绍 RecyclerView 的高级用法。
在这里插入图片描述

目录

  1. 自定义布局管理器
  2. ItemDecoration 装饰
  3. 高级动画控制
  4. 自定义缓存和 RecycledViewPool
  5. 数据差异计算 DiffUtil
  6. 嵌套 RecyclerView 和 ConcatAdapter
  7. 手势交互:拖拽与滑动
  8. 性能优化技巧

1. 自定义布局管理器

LayoutManager 控制 RecyclerView 中每个子项的布局方式。除了 LinearLayoutManagerGridLayoutManager 等系统提供的布局管理器,我们可以自定义 LayoutManager 以实现特殊的布局效果。

示例:创建一个圆形布局管理器
class CircleLayoutManager : RecyclerView.LayoutManager() {private val radius = 300  // 半径private val angleStep = Math.toRadians(360.0 / itemCount)override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams {return RecyclerView.LayoutParams(RecyclerView.LayoutParams.WRAP_CONTENT,RecyclerView.LayoutParams.WRAP_CONTENT)}override fun onLayoutChildren(recycler: RecyclerView.Recycler, state: RecyclerView.State) {detachAndScrapAttachedViews(recycler)val centerX = width / 2val centerY = height / 2for (i in 0 until itemCount) {val view = recycler.getViewForPosition(i)addView(view)measureChildWithMargins(view, 0, 0)val width = getDecoratedMeasuredWidth(view)val height = getDecoratedMeasuredHeight(view)val angle = i * angleStepval x = (centerX + radius * Math.cos(angle) - width / 2).toInt()val y = (centerY + radius * Math.sin(angle) - height / 2).toInt()layoutDecorated(view, x, y, x + width, y + height)}}
}

2. ItemDecoration 装饰

ItemDecoration 用于绘制 RecyclerView 子项的分割线、边框、背景等效果,可以实现比简单的 DividerItemDecoration 更灵活的效果。

示例:实现一个带间距的圆角背景装饰
class RoundedCornerDecoration(private val padding: Int, private val radius: Float) : RecyclerView.ItemDecoration() {private val paint = Paint().apply {color = Color.LTGRAYisAntiAlias = true}override fun onDraw(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) {for (i in 0 until parent.childCount) {val child = parent.getChildAt(i)val rect = RectF(child.left.toFloat() + padding,child.top.toFloat() + padding,child.right.toFloat() - padding,child.bottom.toFloat() - padding)canvas.drawRoundRect(rect, radius, radius, paint)}}
}

3. 高级动画控制

RecyclerView 提供了 ItemAnimator 来管理添加、移除和移动等动画效果。我们可以自定义 ItemAnimator,甚至为不同类型的操作设置不同的动画效果。

示例:创建淡入淡出的动画
class FadeInAnimator : DefaultItemAnimator() {override fun animateAdd(holder: RecyclerView.ViewHolder): Boolean {holder.itemView.alpha = 0fholder.itemView.animate().alpha(1f).setDuration(500).start()return true}override fun animateRemove(holder: RecyclerView.ViewHolder): Boolean {holder.itemView.animate().alpha(0f).setDuration(500).start()return true}
}

4. 自定义缓存和 RecycledViewPool

RecyclerView 提供 RecycledViewPool 来缓存多种类型的视图。设置 RecycledViewPool 可以提升多个 RecyclerView 共享视图缓存的效果,适用于嵌套和切换页面的场景。

示例:设置共享 RecycledViewPool
val sharedPool = RecyclerView.RecycledViewPool()
recyclerView1.setRecycledViewPool(sharedPool)
recyclerView2.setRecycledViewPool(sharedPool)

5. 数据差异计算 DiffUtil

DiffUtil 是高效的数据差异计算工具,用于对比旧数据和新数据并生成操作指令。这对于动态数据列表是非常重要的,可以提升性能并减少不必要的刷新。

示例:使用 DiffUtil 优化数据更新
class MyDiffUtilCallback(private val oldList: List,private val newList: List
) : DiffUtil.Callback() {override fun getOldListSize() = oldList.sizeoverride fun getNewListSize() = newList.sizeoverride fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {return oldList[oldItemPosition].id == newList[newItemPosition].id}override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {return oldList[oldItemPosition] == newList[newItemPosition]}
}// 使用 DiffUtil 进行数据更新
val diffResult = DiffUtil.calculateDiff(MyDiffUtilCallback(oldList, newList))
diffResult.dispatchUpdatesTo(adapter)

6. 嵌套 RecyclerView 和 ConcatAdapter

对于多种类型布局需求,可以使用嵌套的 RecyclerViewConcatAdapter 来管理不同的 Adapter,避免复杂的 RecyclerView.Adapter 实现。

示例:使用 ConcatAdapter 管理多个 Adapter
val adapter1 = Adapter1()
val adapter2 = Adapter2()
val concatAdapter = ConcatAdapter(adapter1, adapter2)
recyclerView.adapter = concatAdapter

7. 手势交互:拖拽与滑动

ItemTouchHelper 支持子项拖拽和滑动。通过 ItemTouchHelper.Callback 实现交互逻辑,并附加到 RecyclerView 上。

示例:实现拖拽和滑动删除
val itemTouchHelperCallback = object : ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP or ItemTouchHelper.DOWN, ItemTouchHelper.LEFT
) {override fun onMove(recyclerView: RecyclerView,viewHolder: RecyclerView.ViewHolder,target: RecyclerView.ViewHolder): Boolean {// 处理拖拽逻辑return true}override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {// 处理滑动删除逻辑}
}ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView)

8. 性能优化技巧

  1. 避免频繁绑定:在 onBindViewHolder 中避免做复杂计算,尽量将静态数据放到 ViewHolder 中。
  2. 预取数据:使用 RecyclerView.setItemViewCacheSize() 或 LinearLayoutManager.setInitialPrefetchItemCount() 来增加缓存。
  3. 调整视图池大小:通过 RecycledViewPool 来共享视图池。
  4. 减少布局嵌套:使用 ConstraintLayout 等优化布局。

通过这些高级用法,可以更灵活地控制 RecyclerView 的行为,从而显著提升应用的用户体验和性能。

参考

Working with RecyclerView in Android & Kotlin

相关文章:

RecyclerView进阶知识讲解

在 Android 开发中,RecyclerView 是一种高效的列表和网格布局控件,用于显示大规模数据。尽管基本使用方法简单,但深入理解并掌握其高级进阶用法能大幅提升用户体验和应用性能。下面,我将从布局管理、动画和手势、自定义缓存、优化…...

C语言 函数

时间:2024.11.10-11.11 一、学习内容 1、什么是函数 函数:程序中独立的功能。将反复书写的代码,又不确定什么时候回用到的代码打包起来。 2、函数的基本格式 函数的定义格式(写在main函数外) void 函数名() { 函数…...

windows中docker安装redis和redisinsight记录

创建一个Redis运行容器,命令如下 docker run -it -d --name redis -p 6379:6379 redis --bind 0.0.0.0 --protected-mode no -d 代表Redis容器后台运行 --name redis 给创建好的容器起名叫redis -p 6379:6379 将容器的6379端口映射到宿主机的6379端口,注…...

itextpdf打印A5的问题

使用A5打印的时候,再生成pdf是没有问题的。下面做了一个测试,在打印机中,使用A5的纸张横向放入,因为是家用打印机,A5与A4是同一个口,因此只能这么放。 使用itextpdf生成pdf,在浏览器中预览pdf是…...

qt QUndoView详解

1、概述 QUndoView 是 Qt 框架中用于显示 QUndoStack(撤销堆栈)内容的视图类。它通常与 QUndoStack 一起使用,为用户提供了一个可视化的界面来查看和操作撤销/重做历史。QUndoView 可以显示堆栈中的每个命令,并允许用户通过界面进…...

python+智谱AI-实现钉钉消息自动回复

python智谱AI-实现钉钉消息自动回复 实现了电脑窗口切换,截图识别未读消息,与语言模型交互后,将答案带入到钉钉窗口中。偷个懒,直接贴代码了,后续不断完善注释,如果遇到读不懂的地方,欢迎交流。…...

Kafka-Eagle的配置——kafka可视化界面

通过百度网盘分享的文件:kafka-eagle-bin-2.0.8.tar.gz 链接:https://pan.baidu.com/s/1H3YONkL97uXbLTPMZHrfdg?pwdsltu 提取码:sltu 一、界面展示 二、软件配置 1、关闭kafka集群 kf.sh stop 2、将该软件上传到/opt/modules下 cd /opt…...

【命令操作】Linux上带宽流量监控nethogs命令详解 _ 统信 _ 麒麟 _ 方德

原文链接:【命令操作】Linux上带宽流量监控nethogs命令详解 | 统信 | 麒麟 | 方德 Hello,大家好啊!今天带来一篇关于Linux上nethogs命令详解的文章。nethogs是一款非常实用的网络流量监控工具,帮助用户实时查看系统中每个进程的网…...

【入门篇】数字统计——多语言版

题目跳转:数字统计 题目解析: 这道题目要求统计在给定范围 [L, R] 内所有整数中数字 2 出现的次数。例如,在范围 [2, 22] 中,数字 2 分别在数 2、12、20、21、22 中出现的次数,最终出现了6次。 题目的输入为两个正…...

探索那些现代C++语法糖

本文来聊聊现代C的一些语法糖。 1.Auto auto x 10; // 推导为 int auto y 3.14; // 推导为 double2.范围-based for 循环 std::vector<int> v {1, 2, 3, 4, 5}; for (auto val : v) {std::cout << val << " "; }3.nullptr int* ptr nullpt…...

【LeetCode】【算法】33. 搜索旋转排序数组

LeetCode 33. 搜索旋转排序数组 题目描述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k…...

Python小游戏25——黄金矿工

首先&#xff0c;你需要安装Pygame库。 如果你还没有安装&#xff0c;可以使用以下命令进行安装&#xff1a; 【bash】 pip install pygame 【python】代码展示 import pygame import random # 初始化Pygame pygame.init() # 设置屏幕尺寸 screen_width 800 screen_height 60…...

WPF中Prism框架中 IContainerExtension 和 IRegionManager的作用

在Prism框架中&#xff0c;IContainerExtension和IRegionManager扮演着重要的角色&#xff0c;具体作用如下&#xff1a; IContainerExtension IContainerExtension接口是Prism 7中引入的&#xff0c;用于抽象依赖注入容器的操作。它实现了IContainerProvider和IContainerReg…...

C++实现用户分组--学习

第一步实现&#xff1a;ETL的设计分三部分&#xff1a;数据抽取(Data Extraction)、数据的清洗转换(Data Transformation)、数据的加载(Data Loading). 构建一个数据容器类&#xff0c;其中包含转换后的MNIST手写数据。还实现了一个数据处理程序&#xff0c;该数据处理程序将提…...

鸿蒙华为商城APP案例

模拟器运行效果如下&#xff1a; 鸿蒙版APP-华为商城-演示视频...

回首遥望-C++内存对齐的思考

这一章节主要巩固一下学习C/C时内存对齐相关的内容&#xff01; 文章目录 什么是内存对齐&#xff1f;为什么要有内存对齐&#xff1f;如何进行内存对齐&#xff1f;致谢&#xff1a; 什么是内存对齐&#xff1f; 这里不提及一堆啰嗦概念&#xff0c;就结合实际出发&#xff0…...

力扣 LeetCode 704. 二分查找(Day1:数组)

解题思路&#xff1a; 二分查找主要分为[ left , right ]左闭右闭和[ left , right )左闭右开两种 此处采取[ left , right ]左闭右闭写法 注意&#xff1a; 1. right的初始化取值 2. while中取等 3. right mid -1 ; class Solution {public int search(int[] nums, i…...

【Mode Management】AUTOSAR架构下唤醒源检测函数EcuM_CheckWakeup详解

目录 前言 正文 1.AUTOSAR标准描述 1.1 EcuM_CheckWakeup用来干什么 1.2 EcuM_CheckWakeup在哪里被调用 1.3 EcuM_CheckWakeup的使用场景 1.3.1 GPT中断检测唤醒源 1.3.2 EcuM轮询GPT检测唤醒源 1.3.3 ICU中断检测唤醒源 1.3.4 其他 2.AUTOSR工具相关配置 3.唤醒源…...

Zabbix基础信息概述

1.Zabbix概述 Zabbix 是一款能够监控各种网络参数以及服务器健康性和完整性的软件。Zabbix 使用灵活的通知机制&#xff0c;允许用户为几乎任何事件配置基于邮件的告警&#xff0c;这样可以快速反馈服务器的问题。基于已存储的数据&#xff0c;Zabbix 提供了出色的报告和数据可…...

SpringBoot(十二)SpringBoot配置redis

接下来我要实现的webscoket即时聊天中需要使用到redis,我先在项目中配置一下redis。 我这里再windows中做测试,关于redis的安装请移步《Redis(三)Windows系统安装redis》 一:在pom.xml中添加依赖 <!-- springboot redis start --><dependency><grou…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

CppCon 2015 学习:Time Programming Fundamentals

Civil Time 公历时间 特点&#xff1a; 共 6 个字段&#xff1a; Year&#xff08;年&#xff09;Month&#xff08;月&#xff09;Day&#xff08;日&#xff09;Hour&#xff08;小时&#xff09;Minute&#xff08;分钟&#xff09;Second&#xff08;秒&#xff09; 表示…...

MySQL体系架构解析(三):MySQL目录与启动配置全解析

MySQL中的目录和文件 bin目录 在 MySQL 的安装目录下有一个特别重要的 bin 目录&#xff0c;这个目录下存放着许多可执行文件。与其他系统的可执行文件类似&#xff0c;这些可执行文件都是与服务器和客户端程序相关的。 启动MySQL服务器程序 在 UNIX 系统中&#xff0c;用…...

Appium下载安装配置保姆教程(图文详解)

目录 一、Appium软件介绍 1.特点 2.工作原理 3.应用场景 二、环境准备 安装 Node.js 安装 Appium 安装 JDK 安装 Android SDK 安装Python及依赖包 三、安装教程 1.Node.js安装 1.1.下载Node 1.2.安装程序 1.3.配置npm仓储和缓存 1.4. 配置环境 1.5.测试Node.j…...