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

Android进阶之路 - RecyclerView停止滑动后Item自动居中(SnapHelper辅助类)

之前一直没注意 SnapHelper 辅助类的功能,去年的时候看到项目中仅通过俩行代码设置 RecyclerView 后就提升了用户体验,觉得还是很有必要了解一下,尝试过后才发现其 PagerSnapHelperLinearSnapHelper 子类可以作用于不同场景,且听吾言

RecyclerView基础

  • Android进阶之路 - RecyclerView基础使用(17年)
  • Android进阶之路 - RecyclerView实现横、纵向滑动列表(19年)
  • Android基础进阶 - RecyclerView列表加载多类型视图

RecyclerView扩展

  • Android进阶之路 - RecyclerView加载多类型视图(ConcatAdapter到底有没有学习必要?)
  • Android进阶之路 - RecyclerView停止滑动后Item自动居中(SnapHelper辅助类)

RecyclerView相关功能

  • Android进阶之路 - RecyclerView左划删除(SwipeRecyclerView的简单使用 17年)
  • Android进阶之路 - RecyclerView列表置顶、滑动到指定条目(18年)
  • Android进阶之路 - RecyclerView列表自动无限水平滚动(21年)
  • Android进阶之路 - 双列表联动效果(18年)

他字字未提喜欢你,你句句都是我愿意

    • 基础了解
    • 实践检验
      • 前置 ItemView
      • 前置 Adapter
      • 使用方式

你在开发项目中遇到过这样的场景吗?

HintRecyclerView 为水平滑动 && 子ItemView 宽度非 match_parent(支持同屏展示多个ItemView

  • 用户滑动列表时产生类似 ViewPager 效果,停止滑动后ItemView 自动居中(一般正常速度滑动只滑动一条数据,但是当滑动速度加快(比较费力时),可能会滑动多条数据
  • 用户正常速度滑动列表时可更轻易的滑动多条数据,停止滑动后子ItemView自动居中

Look效果:如果以下效果不能完全满足,也可以自定义SnapHelper,然后参考其子类实现增添部分你需要的业务功能,例如修改滑动速度等

请添加图片描述

Tip:核心方法仅有俩行,如急于开发,亦可直接使用或直接看实践检验,等有时间再来一同了解

创建对应的 SnapHelper 后通过 attachToRecyclerView 关联 RecyclerView 即可

  • PagerSnapHelper
   val pagerSnapHelper = PagerSnapHelper()pagerSnapHelper.attachToRecyclerView(mRvPager)
  • LinearSnapHelper
   val lineaSnapHelper = LinearSnapHelper()lineaSnapHelper.attachToRecyclerView(mRvLinear)

基础了解

SnapHelper自身为抽象类,同时继承了RecyclerView.OnFlingListener,内部实现了一些通用基类方法,you俩个实现子类,通过重写其中部分方法,从而达到对应的需求效果

  • PagerSnapHelper:类似ViewPager滑动效果,仅支持单条滑动!在 ViewPager控件中也可以看到PagerSnapHelper的身影
  • LinearSnapHelp:水平快速滑动列表,体验丝滑,当滑动停止后,ItemView 自动居中

在这里插入图片描述

OnFlingListener 仅拥有一个抽象方法

在这里插入图片描述

因为我只是通过源码方法命名 + 参考方法注释 简单理解,可能并不是很详细,有兴趣的可以前往早期一位前辈写的 让你明明白白的使用RecyclerView——SnapHelper详解

通过查看 SnapHelper 内部方法,简单分析一下方法作用范围(仅做部分解释,并不完全)

  • 支持 绑定RecyclerView
  • calculateDistanceToFinalSnap 测量移动距离
  • findSnapView 支持 定位移动的View
  • findTargetSnapPosition 支持定位移动后的数据(视图)角标
  • FlingListenerScrollListener 滑动监听&滑动速度监听

在这里插入图片描述

PagerSnapHelperLinearSnapHelper 除基类方法外,支持获取居中View、布局方向等

PagerSnapHelper 源码方法

在这里插入图片描述

LinearSnapHelper 源码方法

在这里插入图片描述

如果要自定义 SnapHelper 的话,需要重新以下三个抽象方法

package com.example.recyclerviewsnaphelperimport android.view.View
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SnapHelperclass OurHelper : SnapHelper() {//计算最终移动距离override fun calculateDistanceToFinalSnap(layoutManager: RecyclerView.LayoutManager, targetView: View): IntArray? {TODO("Not yet implemented")}//获取移动Viewoverride fun findSnapView(layoutManager: RecyclerView.LayoutManager?): View? {TODO("Not yet implemented")}//获取移动View的角标位置override fun findTargetSnapPosition(layoutManager: RecyclerView.LayoutManager?, velocityX: Int, velocityY: Int): Int {TODO("Not yet implemented")}
}

实践检验

RecyclerView 常规使用,仅加入了SnapHelper.attachToRecyclerView相关绑定

前置 ItemView

在这里插入图片描述

item_view

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="250dp"android:layout_height="100dp"android:paddingHorizontal="5dp"><TextViewandroid:id="@+id/tv_data"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#f98741"android:gravity="center"android:text="Item Data"android:textColor="#ffffff"android:textStyle="bold" />
</androidx.appcompat.widget.LinearLayoutCompat>

前置 Adapter

package com.example.recyclerviewsnaphelperimport android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerViewclass OurAdapter(private val dataList: MutableList<String>) : RecyclerView.Adapter<OurAdapter.OurViewHolder>() {override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OurViewHolder {return OurViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_view, parent,false))}override fun getItemCount(): Int {return dataList.size}override fun onBindViewHolder(holder: OurViewHolder, position: Int) {holder.itemView.findViewById<TextView>(R.id.tv_data).text=dataList[position]}inner class OurViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
}

使用方式

package com.example.recyclerviewsnaphelperimport android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.LinearSnapHelper
import androidx.recyclerview.widget.PagerSnapHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.HORIZONTALclass MainActivity : AppCompatActivity() {var dataList = mutableListOf<String>()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)//数据模拟for (i in 0..15) {dataList.add("第${i + 1}页")}//RecyclerView基础配置pagerRecyclerSetting()layoutRecyclerSetting()}/*** RecyclerView基础配置:PagerSnapHelper示例* */private fun pagerRecyclerSetting() {val mRvPager = findViewById<RecyclerView>(R.id.rv_pager)var layoutManager = LinearLayoutManager(this)layoutManager.orientation = HORIZONTALmRvPager.layoutManager = layoutManagerval ourPagerAdapter = OurAdapter(dataList)mRvPager.adapter = ourPagerAdapter//添加SnapHelper相关辅助类val pagerSnapHelper = PagerSnapHelper()pagerSnapHelper.attachToRecyclerView(mRvPager)}/*** RecyclerView基础配置:LinearSnapHelper示例* */private fun layoutRecyclerSetting() {val mRvLinear = findViewById<RecyclerView>(R.id.rv_linear)var layoutManager = LinearLayoutManager(this)layoutManager.orientation = HORIZONTALmRvLinear.layoutManager = layoutManagerval ourLayoutAdapter = OurAdapter(dataList)mRvLinear.adapter = ourLayoutAdapter//添加SnapHelper相关辅助类val lineaSnapHelper = LinearSnapHelper()lineaSnapHelper.attachToRecyclerView(mRvLinear)}
}

activity_main

  • 预览图

在这里插入图片描述

  • layout布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat 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"android:orientation="vertical"tools:context=".MainActivity"><TextViewandroid:layout_width="match_parent"android:layout_height="40dp"android:gravity="center"android:text="PagerSnapHelper效果"android:textStyle="bold" /><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/rv_pager"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"tools:itemCount="10"tools:listitem="@layout/item_view" /><TextViewandroid:layout_width="match_parent"android:layout_height="40dp"android:layout_marginTop="50dp"android:gravity="center"android:text="LinearSnapHelper"android:textStyle="bold" /><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/rv_linear"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"tools:itemCount="10"tools:listitem="@layout/item_view" /></androidx.appcompat.widget.LinearLayoutCompat>

相关文章:

Android进阶之路 - RecyclerView停止滑动后Item自动居中(SnapHelper辅助类)

之前一直没注意 SnapHelper 辅助类的功能&#xff0c;去年的时候看到项目中仅通过俩行代码设置 RecyclerView 后就提升了用户体验&#xff0c;觉得还是很有必要了解一下&#xff0c;尝试过后才发现其 PagerSnapHelper、LinearSnapHelper 子类可以作用于不同场景&#xff0c;且听…...

高性能图表组件LightningChart .NET v11.0发布——增强DPI感知能力

LightningChart完全由GPU加速&#xff0c;并且性能经过优化&#xff0c;可用于实时显示海量数据-超过10亿个数据点。 LightningChart包括广泛的2D&#xff0c;高级3D&#xff0c;Polar&#xff0c;Smith&#xff0c;3D饼/甜甜圈&#xff0c;地理地图和GIS图表以及适用于科学&am…...

神经网络系列---计算图基本原理

文章目录 计算图符号微分符号微分的步骤示例符号微分在计算图中的使用总结 数值微分前向差分法中心差分法数值微分的使用注意事项总结 自动微分1. 基本原理2. 主要类型3. 计算图4. 应用5. 工具和库6. 优点和缺点 计算图1. **计算图的建立**2. **前向传播**3. **反向传播**4. **…...

3D数字孪生

数字孪生&#xff08;Digital Twin&#xff09;是物理对象、流程或系统的虚拟复制品&#xff0c;用于监控、分析和优化现实世界的对应物。 这些数字孪生在制造、工程和城市规划等领域变得越来越重要&#xff0c;因为它们使我们能够在现实世界中实施改变之前模拟和测试不同的场景…...

C++惯用法之空基类优化

相关系列文章 C惯用法之Pimpl C惯用法之CRTP(奇异递归模板模式) C之std::tuple(二) : 揭秘底层实现原理 目录 1.空类 2.空基类优化 3.内存布局原则 4.实例分析 5.总结 1.空类 C 中每个对象的实例都可以通过取地址运算符获取其在内存布局中的开始位置&#xff0c;因此每个类…...

【生成式AI】ChatGPT 原理解析(2/3)- 预训练 Pre-train

Hung-yi Lee 课件整理 预训练得到的模型我们叫自监督学习模型&#xff08;Self-supervised Learning&#xff09;&#xff0c;也叫基石模型&#xff08;foundation modle&#xff09;。 文章目录 机器是怎么学习的ChatGPT里面的监督学习GPT-2GPT-3和GPT-3.5GPTChatGPT支持多语言…...

Day03:Web架构OSS存储负载均衡CDN加速反向代理WAF防护

目录 WAF CDN OSS 反向代理 负载均衡 思维导图 章节知识点&#xff1a; 应用架构&#xff1a;Web/APP/云应用/三方服务/负载均衡等 安全产品&#xff1a;CDN/WAF/IDS/IPS/蜜罐/防火墙/杀毒等 渗透命令&#xff1a;文件上传下载/端口服务/Shell反弹等 抓包技术&#xff1a…...

C++多线程同步(上)

多线程同步 引言总述详情互斥锁示例运行结果分析条件变量示例一实现分析优化运行结果示例二实现代码运行结果示例三实现代码运行结果读写锁示例实现代码注意分析运行结果附言实现运行结果运行结果个人心得引言 项目中使用多线程,会遇到两种问题,一种是对共享资源的访问时需要…...

猜猜心里数字(个人学习笔记黑马学习)

1.定义一个变量&#xff0c;数字类型&#xff0c;内容随意 2.基于input语句输入猜想的数字&#xff0c;通过if和多次elif的组合&#xff0c;判断猜想数字是否和心里数字一致 num5if int(input("请输入第一次猜想的数字&#xff1a;"))5:print("猜对了&#xff0…...

实用Pycharm插件

Pycharm的离线安装&#xff1a;https://plugins.jetbrains.com/ 需要根据对应的Pycharm/Goland版本选取所需的 对于实用的插件如下&#xff1a; 实时查看每一行的git blame信息&#xff1a; Gittoolbox 转换IDE的英文为中文&#xff1a;Chinese IDE侧格式化json字符串&#…...

数据结构试题练习

(1). 假如队列未满&#xff0c;现有变量data需要入队,请写出表达式; if( (tail1)%SEQLEN ! head ) {seqn[tail] data;tail (tail1)%SEQLEN; } (2). 假如队列未空&#xff0c;现在需要从队列取一个元素并赋值给变量data&#xff0c;请写出表达式; if( head ! tail ) {data se…...

s-table和columns初始化不完整,造成table文件的filter报错

问题 顺藤摸瓜找errorHandler.js文件 发现文件并没有什么问题 顺藤摸瓜找index.vue文件 首先找到报错的filter&#xff0c;发现与columnsSetting相关 找到columnsSetting发现等于columns 返回自己使用S-table组件的地方&#xff0c;发现columns初始化时仅初始化为ref()未表明…...

SLA 是什么?如何实现 SLA 管理

随着业务的不断壮大&#xff0c;为了满足日益增长的客户需求&#xff0c;网络必须保持与这些需求同步。同时&#xff0c;为了提高最终用户的体验&#xff0c;运维人员/网络管理员在监控企业级网络时遇到了不少瓶颈&#xff0c;必须不断审查网络&#xff0c;以确保提供的服务质量…...

火灾安全护航:火灾监测报警摄像机助力建筑安全

火灾是建筑安全中最常见也最具破坏力的灾难之一&#xff0c;为了及时发现火灾、减少火灾造成的损失&#xff0c;火灾监测报警摄像机应运而生&#xff0c;成为建筑防火安全的重要技术装备。 火灾监测报警摄像机采用高清晰度摄像头和智能识别系统&#xff0c;能够全天候监测建筑内…...

JavaScript 基础学习笔记(五):函数、作用域、匿名函数

目录 一、函数 1.1 声明和调用 1.2 形参和实参 1.3 返回值 二、作用域 2.1 全局作用域 2.2 局部作用域 三、匿名函数 3.1 函数表达式 3.2 立即执行函数 一、函数 理解函数的封装特性&#xff0c;掌握函数的语法规则 1.1 声明和调用 函数可以把具有相同或相似逻辑的代…...

Qt环境配置VTK

Qt与VTK的结合为开发者提供了强大的跨平台图形界面开发能力和三维可视化处理能力。本教程旨在详细介绍如何配置Qt环境以使用VTK库&#xff0c;从而为开发者打造高效、强大的三维可视化应用。 一、准备工作 在开始之前&#xff0c;确保您的开发环境中已经安装了Qt和CMake。Qt提…...

腾讯云最新活动_腾讯云促销优惠_代金券-腾讯云官网入口

腾讯云服务器多少钱一年&#xff1f;62元一年起&#xff0c;2核2G3M配置&#xff0c;腾讯云2核4G5M轻量应用服务器218元一年、756元3年&#xff0c;4核16G12M服务器32元1个月、312元一年&#xff0c;8核32G22M服务器115元1个月、345元3个月&#xff0c;腾讯云服务器网txyfwq.co…...

如何创建自己的Spring Boot Starter并为其编写单元测试

当我们想要封装一些自定义功能给别人使用的时候&#xff0c;创建Spring Boot Starter的形式是最好的实现方式。如果您还不会构建自己的Spring Boot Starter的话&#xff0c;本文将带你一起创建一个自己的Spring Boot Starter。 快速入门 创建一个新的 Maven 项目。第三方封装的…...

数据分析---常见处理逻辑

目录 数据清洗数据转换数据聚合数据筛选增删改查(以查为例)数据清洗 去除重复值:使用DISTINCT关键字去除重复行。//这将返回一个包含所有不重复城市的结果集 SELECT DISTINCT city FROM students;处理缺失值:使用IS NULL或IS NOT NULL判断是否为空值,并使用COALESCE或CASE…...

2024-02-26(金融AI行业概览与大数据生态圈)

1.最开始的风控是怎么做的&#xff1f; 人审 吃业务经验 不能大批量处理&#xff0c;效率低下 不适用于移动互联网的金融场景 2.建模的概念 建模就是构造一个数学公式&#xff0c;能将我们手上有的数据输入进去&#xff0c;通过计算得到一些预测结果。 比如初高中学习的…...

从CCF A类清单看计算机学科前沿:如何选择你的学术发表阵地

1. CCF A类清单&#xff1a;计算机学术圈的"米其林指南" 第一次看到CCF A类清单时&#xff0c;我正为博士开题选方向发愁。导师甩给我这份列表说&#xff1a;"这就是计算机学界的米其林三星榜单&#xff0c;发一篇能顶三篇普通论文。"后来我才理解&#x…...

区块链应用·数据共享消除数字鸿沟

基于FISCO BCOS与Go语言构建可信数据共享基础设施,打通跨机构、跨地域的信任壁垒 一、数字鸿沟的根源:信任缺失下的“数据孤岛” 数字鸿沟(Digital Divide)不仅存在于不同区域、不同群体之间,更深层次地体现在数据持有者之间的信任鸿沟。在传统信息系统中,数据分散存储于…...

别急着改代码!Selenium被Gitee拦截后,我靠手动点一下按钮就解决了

当技术手段失效时&#xff1a;一个手动点击如何破解Selenium爬虫封锁 那天下午&#xff0c;我的屏幕又一次弹出了那个熟悉的红色警告框——"检测到您的访问可能存在安全风险"。这已经是第七次了。作为一个习惯用代码解决问题的开发者&#xff0c;我本能地打开了Chro…...

在 Xcode 中运行和调试单元测试:使用 Debug 和日志

单元测试是确保代码质量的重要手段&#xff0c;而运行和调试测试是开发者必备的技能。本文将介绍如何在 Xcode 中运行单元测试&#xff0c;并使用调试和日志工具来发现和解决问题。 运行单元测试 1. 设置测试目标 在 Xcode 中&#xff0c;为项目添加一个新的测试目标&#x…...

用Python和NumPy分析心电图:手把手教你找出QRS波的核心频率(附完整代码)

用Python和NumPy分析心电图&#xff1a;手把手教你找出QRS波的核心频率&#xff08;附完整代码&#xff09; 在生物医学信号处理领域&#xff0c;心电图&#xff08;ECG&#xff09;分析一直是研究热点。QRS波作为ECG信号中最显著的特征之一&#xff0c;其频率分布直接反映了心…...

别再手动编译了!用GitHub Actions自动编译你的专属OpenWRT固件(基于KFERMercer脚本)

GitHub Actions自动化编译OpenWRT固件实战指南 1. 云端编译革命&#xff1a;告别传统编译方式 对于OpenWRT开发者而言&#xff0c;本地编译固件一直是项耗时且资源密集的任务。传统方式需要配置完整的Linux编译环境&#xff0c;消耗大量计算资源&#xff0c;且受限于本地硬件性…...

5分钟掌握可视化Cron表达式生成:告别手动配置的烦恼

5分钟掌握可视化Cron表达式生成&#xff1a;告别手动配置的烦恼 【免费下载链接】no-vue3-cron 这是一个 cron 表达式生成插件,基于 vue3.0 与 element-plus 实现 项目地址: https://gitcode.com/gh_mirrors/no/no-vue3-cron 还在为复杂的Cron表达式语法而头疼吗&#x…...

从单兵到军团:2026 多智能体协作的崛起与实战全指南

从单兵到军团&#xff1a;2026 多智能体协作的崛起与实战全指南在前三篇文章中&#xff0c;我们拆解了单个AI Agent的技术内核&#xff0c;并盘点了2026年主流框架的选型策略。但企业级场景的复杂程度&#xff0c;正在以肉眼可见的速度超越单一个体的能力天花板。单个“全能实习…...

QSpectrumAnalyzer终极指南:3步掌握多平台SDR频谱分析

QSpectrumAnalyzer终极指南&#xff1a;3步掌握多平台SDR频谱分析 【免费下载链接】qspectrumanalyzer Spectrum analyzer for multiple SDR platforms (PyQtGraph based GUI for soapy_power, hackrf_sweep, rtl_power, rx_power and other backends) 项目地址: https://git…...

解锁BT下载速度瓶颈:92个公共Tracker节点让你的下载体验飞升

解锁BT下载速度瓶颈&#xff1a;92个公共Tracker节点让你的下载体验飞升 【免费下载链接】trackerslist Updated list of public BitTorrent trackers 项目地址: https://gitcode.com/GitHub_Trending/tr/trackerslist 还在为BT下载速度慢、种子健康度低而烦恼吗&#x…...