ViewPager2一页展示多个Item且两边滑动

2023-11-07

ViewPager2一页展示多个Item且两边滑动

研究背景

在项目中有一个滚轮选择器的需求,对于小组件的研发,我一直倾向于自研,一方面功能不复杂,另一方面也锻炼自己的思维能力。不只是局限于上次研发。

传统Viewpager解决方法

对于传统的Viewpager的解决方法是

 <androidx.viewpager.widget.ViewPager
            android:layout_width="match_parent"
            android:clipToPadding="false"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:gravity="center_horizontal"
            android:layout_height="300dp"/>

这个就可以了。

Viewpager2解决方法

布局上不能截断子类绘制

<androidx.viewpager2.widget.ViewPager2
        android:layout_width="match_parent"
        android:layout_height="135dp"
        android:clipChildren="false"
        android:orientation="vertical" />

代码上,需要捞出里面真正实现的RecyclerView

 		RecyclerView recyclerView = (RecyclerView) mPager.getChildAt(0);
        int padding = ScreenUtil.dip2px(45);
        recyclerView.setPadding(0, padding, 0, padding);
        recyclerView.setClipToPadding(false);

原理分析

Viewpager

如果我们查看源码,在Viewpager中

public class ViewPager extends ViewGroup {
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
     	//做点击事件处理
     }
}

自己来实现所有Viewpager的功能,代码量巨大。我们的每个Item都是ViewpagerchildView

所以,我们做padding还有不截断,都是直接作用在childView上的。

Viewpager2

但是,在Viewpager2上是不一样的。

public final class ViewPager2 extends ViewGroup {
	//Java中默认私有的,所以直接拿不到
	RecyclerView mRecyclerView;
	
	//每个构造函数,都做了相同操作
	public ViewPager2(@NonNull Context context) {
        super(context);
        initialize(context, null);
    }
    
	//初始化方法
	private void initialize(Context context, AttributeSet attrs) {
		//已省略无用代码
        mRecyclerView = new RecyclerViewImpl(context);
        mLayoutManager = new LinearLayoutManagerImpl(context);
        mRecyclerView.setLayoutManager(mLayoutManager);
        setOrientation(context, attrs);
        mRecyclerView.setLayoutParams(
                new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        attachViewToParent(mRecyclerView, 0, mRecyclerView.getLayoutParams());
    }
    
    //源码注释翻译
    //稍微修改了RecyclerView,以获得ViewPager行为在可访问性和启用/禁用用户滚动。
    private class RecyclerViewImpl extends RecyclerView {
        RecyclerViewImpl(@NonNull Context context) {
            super(context);
        }

        @RequiresApi(23)
        @Override
        public CharSequence getAccessibilityClassName() {
            if (mAccessibilityProvider.handlesRvGetAccessibilityClassName()) {
                return mAccessibilityProvider.onRvGetAccessibilityClassName();
            }
            return super.getAccessibilityClassName();
        }

        @Override
        public void onInitializeAccessibilityEvent(@NonNull AccessibilityEvent event) {
            super.onInitializeAccessibilityEvent(event);
            event.setFromIndex(mCurrentItem);
            event.setToIndex(mCurrentItem);
            mAccessibilityProvider.onRvInitializeAccessibilityEvent(event);
        }

        @SuppressLint("ClickableViewAccessibility")
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            return isUserInputEnabled() && super.onTouchEvent(event);
        }

        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            return isUserInputEnabled() && super.onInterceptTouchEvent(ev);
        }
    }
}

我们不用去分析里面怎么做的处理。其实很简单就能看出他是一种什么样的设计。

  • 在Viewpager2中,对RecyclerView进行了包装。RecyclerViewImpl 就是一个包装类。
  • 真正实现滑动行为的是里面的RecyclerView。而Viewpager2可以认为是另一个包装类,也是另一个容器。

所以,我们针对Viewpager2的解决方法就很好理解了。拿到里面真正盛放childViewRecyclerView。再进行paddingclip的设置。

总结

viewpager2的设计内部采用了RecyclerView,这个官方文档说的很清楚。但是,是采用包装的方式。优点在于有了RecyclerView很好用的复用机制。但是,无形中增加了一个页面层级。(这个缺点在优点面前,确实不算什么。但是需要知道。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ViewPager2一页展示多个Item且两边滑动 的相关文章

  • 在包“android”中找不到属性“backgroundTint”的资源标识符

    我发现了一些视图 xml 属性 例如backgroundTint backgroundTintMode 但是当我使用它作为视图属性定义时 Eclipse 显示错误 No resource identifier found for attri
  • Sqlite数据库生命周期?关闭应用程序后它会被删除吗?

    我正在遵循一个简单的教程 该教程创建一个从 SQLiteOpenHelper 扩展的类 并创建一个包含一个表和 5 行的数据库 好的 但我需要更多地了解 android Sqlite 数据库 例如 如果应用程序关闭或手机关机会发生什么 数据
  • 在 ViewPager Fragments 中使用 Master/Detail 模板(下载链接)

    工作代码 https github com lukeallison ViewPagerMasterDetail https github com lukeallison ViewPagerMasterDetail Android 主 详细流
  • CardView 圆角获得意想不到的白色

    When using rounded corner in CardView shows a white border in rounded area which is mostly visible in dark environment F
  • 计数物体和更好的填充孔的方法

    我是 OpenCV 新手 正在尝试计算物体的数量在图像中 我在使用 MATLAB 图像处理工具箱之前已经完成了此操作 并在 OpenCV Android 中也采用了相同的方法 第一步是将图像转换为灰度 然后对其进行阈值计算 然后计算斑点的数
  • Android Activity 生命周期函数基础知识

    我正在测试这段代码 它显示活动所处的状态 public class Activity101Activity extends Activity String tag Lifecycle Called when the activity is
  • 在画布上绘图

    我正在编写一个 Android 应用程序 它可以在视图的 onDraw 事件上直接绘制到画布上 我正在绘制一些涉及单独绘制每个像素的东西 为此我使用类似的东西 for int x 0 x lt xMax x for int y 0 y lt
  • 带有 EditText 和 Spinner 的对话框

    我有一个按钮 单击后会弹出一个对话框 我希望对话框有一个EditText and a Spinner对话框内 我不知道如何设置它的视图 我有一个代码AlertDialog它有效 只是EditText and Spinner我需要将其放入其中
  • 尝试将相机切换回前面但出现异常

    尝试将相机切换回前面 但出现异常 找不到 问题请检查并帮助 error 01 27 11 49 00 376 E AndroidRuntime 30767 java lang RuntimeException Unable to start
  • 如何在PreferenceActivity中添加工具栏

    我已经使用首选项创建了应用程序设置 但我注意到 我的 PreferenceActivity 中没有工具栏 如何将工具栏添加到我的 PreferenceActivity 中 My code 我的 pref xml
  • Ubuntu 16.04 - Genymotion:找不到 /dev/hw_random

    I install Genymotion on the Ubuntu 16 04 64Bit I created a virtual emulator for Android 6 0 then I run this emulator but
  • 在 SQLite 中搜索时排除 HTML 标签和一些 UNICODE 字符

    更新 4 我已经成功运行了firstchar例如 但现在的问题是使用regex 即使包含头文件 它也无法识别regex操作员 有什么线索可以解决这个问题吗 更新 2 我已经编译了sqlite3我的项目中的库 我现在正在寻找任何人帮助我为我的
  • Google 云端硬盘身份验证异常 - 需要许可吗? (v2)

    我一直在尝试将 Google Drive v2 添加到我的 Android 应用程序中 但无法获得授权 我收到 UserRecoverableAuthIOException 并显示消息 NeedPermission 我感觉 Google A
  • 如何发布Android .aar源以使Android Studio自动找到它们?

    我正在将库发布到内部 Sonatype Nexus 存储库 Android Studio 有一个功能 可以自动查找通过 gradle 引用的库的正确源 我将 aar 的源代码作为单独的 jar 发布到 Nexus 但 Android Stu
  • 如何使用InputConnectionWrapper?

    我有一个EditText 现在我想获取用户对此所做的所有更改EditText并在手动将它们插入之前使用它们EditText 我不希望用户直接更改中的文本EditText 这只能由我的代码完成 例如通过使用replace or setText
  • 如何默认在 ActionOpenDocument 意图中显示“内部存储”选项

    我需要用户选择一个自定义文件类型的文件 并将其从 Windows 文件资源管理器拖到 Android 设备上 但默认情况下内部存储选项不可用 当我使用以下命令启动意图时 var libraryIntent new Intent Intent
  • Android访问远程SQL数据库

    我可以直接从 Android 程序访问远程 SQL 数据库 在网络服务器上 吗 即简单地打开包含所有必需参数的连接 然后执行 SQL 查询 这是一个私人程序 不对公众开放 仅在指定的手机上可用 因此我不担心第三方获得数据库访问权限 如果是这
  • Android Studio - Windows 7 上的 Android SDK 问题

    我对 Google i o 2013 上发布的最新开发工具 Android Studio 有疑问 我已经成功安装了该程序并且能够正常启动 我可以导入现有项目并对其进行编辑 但是 当我尝试单击 SDK 管理器图标或 AVD 管理器图标时 或者
  • 我的设备突然没有显示在“Android 设备选择器”中

    我正在使用我的三星 Galaxy3 设备来测试过去两个月的应用程序 它运行良好 但从今天早上开始 当我将设备连接到系统时 它突然没有显示在 Android 设备选择器 窗口中 我检查过 USB 调试模式仅在我的设备中处于选中状态 谁能猜出问
  • 如何确定对手机号码的呼叫是本地呼叫还是 STD 或 ISD

    我正在为 Android 开发某种应用程序 但不知道如何获取被叫号码是本地或 STD 的号码的数据 即手机号码检查器等应用程序从哪里获取数据 注意 我说的是手机号码 而不是固定电话 固定电话号码 你得到的数字是字符串类型 因此 您可以获取号

随机推荐

  • Qt 读取多行文本框中的内容

    本文介绍将plainTextEdit中的多行文本内容按行读取为字符串的方法 QTextDocument doc ui gt plainTextEdit gt document 将plainTextEdit中的内容读取到doc中 int co
  • 【Kubernetes系列】Container(容器)

    文章目录 Container Container Image 容器镜像 镜像名称 更新镜像 镜像拉取策略 默认镜像拉取策略 强制拉去镜像 ImagePullBackOff 使用私有仓库 容器环境 容器信息 集群信息 Runtime Clas
  • pycharm如何安装pythoncard_pycharm的各种设置,配置

    本博客一直在同步更新中 内容包含 pycharm学习技巧 Learning tips PyCharm3 0默认快捷键 翻译的 pycharm常用设置 pycharm环境和路径配置 Pycharm实用拓展功能 pycharm中清除已编译 py
  • 有关数据结构上机实验的问题

    1 收到学弟提醒 http chuantu xyz t6 741 1605524547x 1566660945 png 本实验不允许公开实验代码 2 原专栏设置付费 本意是希望大家不要再看了 但是有同学订阅了 特此表示歉意 考虑不周 3 原
  • Python爬虫怎么挣钱?6个Python爬虫赚钱方式,搞搞副业不是问题

    1 最典型的就是找爬虫外包活儿 网络爬虫最通常的的挣钱方式通过外包网站 做中小规模的爬虫项目 向甲方提供数据抓取 数据结构化 数据清洗等服务 新入行的程序员大多都会先尝试这个方向 直接靠技术手段挣钱 这是我们技术人最擅长的方式 因项目竞价的
  • redis监控命令monitor(监控内容写入文件)

    redis有一个monitor命令 使用该命令可以实时监控redis正在执行的命令 先登录redis集群 redis app 3 2 12 bin redis cli h 192 168 177 122 p 6379 a abcdef c
  • USB数据线串联电阻知识总结

    一 为什么USB的特性阻抗为90欧姆 USB设备具有简单易用 支持热插拔 速度快等特点 很快被广泛应用于个人电脑和移动设备等信息通讯产品 并扩展至摄影器材 数字电视 机顶盒 游戏机等其它相关领域 可以说USB是目前最为成功的I O技术 而且
  • DDOS高防IP的用途

    DDOS高防IP是为了应对互联网的DDOS攻击而产生的一款付费增值产品 那么该怎么使用呢 DDOS高防IP根据不同的业务接入的方法也不同 在开通这款DDOS高防IP时服务商会给到对应的高防IP作为对外IP和业务IP使用 游戏业务就需要将之前
  • 带你看懂CTC算法

    转自 https zhuanlan zhihu com p 161186907 在文本识别模型CRNN中 涉及到了CTC算法的使用 由于算法的原理涉及内容较多 所以特另开一篇文章对其原理进行叙述 自己在学习CTC过程中也是看了诸多资料才大概
  • 【AI面试】损失函数(Loss),定义、考虑因素,和怎么来的

    神经网络学习的方式 就是不断的试错 知道了错误 然后沿着错误的反方向 梯度方向 不断的优化 就能够不断的缩小与真实世界的差异 此时 如何评价正确答案与错误答案 错误的有多么的离谱 就需要一个评价指标 这时候 损失和损失函数就运用而生 开始之
  • 终端软件MobaXterm新建会话与本地虚拟机连接失败原因分析:Network error: connection refused

    一 首先第一步 检查虚拟机与本机的连通性 在本机powershell终端执行ping 虚拟机ip 虚拟机ip的获取实在虚拟机中执行ifconfig 第一个四位数字就是ip地址 二 ping过之后 发现很正常 那就检查ssh ps e gre
  • Java中的基础----序列化与反序列化的作用

    Java提供两种对象持久化的方式 分别序列化和外部序列化 1 序列化 Serialization 在分布式环境下 无论是何种数据 都会以二进制序列的形式在网络上传输 序列化是一种将对象以一连串的字节描述的过程 用于解决在对对象流进行读写操作
  • Unicode 编码表下载

    概述 很多项目都使用了Unicode 编码表 在此 做个笔录 官网 1 第一入口 https home unicode org 2 第二入口 Unicode 14 0 Character Code Charts 3 第三入口 http ww
  • 如何获得ISO测试版软件,苹果发布iOS11.4 beta2公测版 如何申请iOS11公测资格

    在对应开发者版本推送一天之后 苹果今天凌晨又向公测用户推送了 iOS 11 4 和 tvOS 11 4 的第二个测试版系统更新 iOS 11 4 的 beta 版系统主要用来测试隔空播放 2 以及 iCloud 信息等新功能 tvOS 11
  • 流畅交互体验:实现Vue中el-dialog拖动效果的完美指南

    在使用elementUI中的Dialog组件时 总有无理的产品提需求 在右上角增加可点击全屏的功能 给我实现弹出框可任意拖拽的功能 这种情况下 组件就不能很好的使用了 那么 只能由我们前端攻城狮进行代码攻克了 接下来就实现其中的可拖拽功能
  • UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 2: illegal multibyte sequence

    最近在搞人工智能的东东 玩了玩词云的东西 在编写代码时 出现了一个问题 目的 统计西游记里出现的词的内容 读取西游记整本小说的内容 然后进行统计分析 代码如下 text open 西游记 txt read 但是在执行的时候一直报错 Unic
  • 方舟生存进化秘籍大全

    代码大全 addexperience 10000 0 0 1 给角色加1W经验 可以修改数值 修改人物每升级一次 各种属性的增长倍率 修改文件 common ARK ShooterGame Saved Config WindowsNoEdi
  • adb刷入第三方recovery_【玩机必会技能】小米手机通用刷TWRP RECOVERY

    点击上方 蓝字 关注我们 想让自己的手机获取更多的功能和体验不同的安卓系统 掌握下面这些是必不可少的 此教程也适用于其他品牌的安卓手机 步骤都是一样的 刷入TWRP RECOVERY 这是手机刷入ROOT和第三方ROM的必备工具 而解Boo
  • hualinux2.21 环境搭建:Centos8安装 LVS+keepalived高可用负载均衡

    在前面讲了 hualinux2 19 环境搭建 Centos8 nginx负载均衡 反代 和 hualinux2 20 环境搭建 centos8源安装haproxy 两个常用的负载均衡 基本上都是推荐做七层负载 虽然也有四层负载的能力 现在
  • ViewPager2一页展示多个Item且两边滑动

    ViewPager2一页展示多个Item且两边滑动 研究背景 在项目中有一个滚轮选择器的需求 对于小组件的研发 我一直倾向于自研 一方面功能不复杂 另一方面也锻炼自己的思维能力 不只是局限于上次研发 传统Viewpager解决方法 对于传统