关于安卓viewpager实现堆叠卡片交互

news2024/12/23 10:20:50

背景

长江后浪推前浪,无聊的需求一浪接一浪。
最近做到一个关于卡片堆叠的需求,觉得挺有意思,所以特此记录一下。

文末将附上源码链接

首先看设计图:
在这里插入图片描述
可以看到,是一个卡片堆叠的效果,关于这种UI的实现,方法有很多,例如用recyclerview,viewpager,甚至说自定义view都可以实现,本文将讲述如何使用viewpager实现这种效果。

开发环境

win10
jdk 8
as 4+

实现效果

在这里插入图片描述
由于是demo的演示,所以就不用过多在意颜色,基础功能实现即可。

问题

1、如何修改viewpager的一个卡片堆叠位置
2、如何在滑动的过程中,动态去修改卡片的宽高

思路

对于viewpager中,有个ViewPager.PageTransformer的属性,这个属性是用来干嘛的?
看一下源码的描述:

    /**
     * A PageTransformer is invoked whenever a visible/attached page is scrolled.
     * This offers an opportunity for the application to apply a custom transformation
     * to the page views using animation properties.
     *
     * <p>As property animation is only supported as of Android 3.0 and forward,
     * setting a PageTransformer on a ViewPager on earlier platform versions will
     * be ignored.</p>
     */
    public interface PageTransformer {
        /**
         * Apply a property transformation to the given page.
         *
         * @param page Apply the transformation to this page
         * @param position Position of page relative to the current front-and-center
         *                 position of the pager. 0 is front and center. 1 is one full
         *                 page position to the right, and -1 is one page position to the left.
         */
        void transformPage(@NonNull View page, float position);
    }

简单来讲,就是控制页面的进出场的,简单的你可以用该类实现一些viewpager页面切换进出场的效果,复杂一点的,可以动态计算viewpager滑动过程中,相关view的一个控件属性,等等。

通过继承方式,继承PageTransformer实现一个子类,重写其中的
void transformPage(@NonNull View page, float position);方法。
该方法中,第一个参数就是滑动中的view对象。第二参数,就是view的相对滑动位置。这里要注意,不是view在viewpager中的位置,仅仅是一个滑动位置,简单粗暴地可以理解为是
“负右正左零中间”。当position为0的时候,就是当前显示view,同样地-1,就是0的左边,1就是0的右边。如下图
在这里插入图片描述
这里的0,就是相对于position等于0的情况。

以上就是关于transformPage方法中,参数回调情况的描述。

---------------------------------分割线-------------------------------------

既然有了view对象,有了position左右滑动的回调,那么,就可以做很多事情了。首先position的数值,是受viewpager左右滑动影响,右滑为负数,左滑为正数。这个时候,可以根据左右滑动,做一些控件大小的转换!
注意,在数据处理的过程中,position的正负值影响。

实现

1、实现viewpager的卡片堆叠
通过setTranslationX,可以设置view的x位置!
通过LayoutParams,可以设置view的右侧边距!


设想一下,通过setTranslationX设置一个负值,是不是可以吧viewpager第二个位置的view直接放到第一个view的位置?只不过说,放完以后还是会被第一个view遮挡,导致看不到而已如此类推,就完成了一个viewpager中,view的位置摆放了。


再到LayoutParams,那不是送分题?根据position直接设置右边距,那不就得了吗?


说到这里,相信大部分人都已经懂了。
不懂的也没有关系,可以看下下面的代码:


    @Override
    public void transformPage(@NonNull View view, float position) {
        int pagerWidth = boundViewPager.getWidth();
        LogUtil.d("transformPage tag: " + view.hashCode() + " pos: " + position + " pagerWidth: " + pagerWidth);
        float scaleWidth = pagerWidth * CENTER_PAGE_SCALE;
        float widthInterval = (pagerWidth - scaleWidth) / 2;

        view.setScaleX(CENTER_PAGE_SCALE);
        view.setScaleY(CENTER_PAGE_SCALE);

        //设置间距----------------------------------------------------------------------
        ViewGroup llRoot = view.findViewById(R.id.llRoot);
        if (llRoot != null) {
            ViewGroup.LayoutParams layoutParams = llRoot.getLayoutParams();
            if (layoutParams instanceof RelativeLayout.LayoutParams) {
                ((RelativeLayout.LayoutParams) layoutParams).setMarginEnd((int) ((2 - Math.abs(position)) * endInterval));
                ((RelativeLayout.LayoutParams) layoutParams).topMargin = (int) (Math.abs(position) * verticalInterval);
                ((RelativeLayout.LayoutParams) layoutParams).bottomMargin = (int) (Math.abs(position) * verticalInterval);
                llRoot.setLayoutParams(layoutParams);
            } else if (layoutParams instanceof CardView.LayoutParams) {
                ((FrameLayout.LayoutParams) layoutParams).setMarginEnd((int) ((2 - Math.abs(position)) * endInterval));
                ((FrameLayout.LayoutParams) layoutParams).topMargin = (int) (Math.abs(position) * verticalInterval);
                ((FrameLayout.LayoutParams) layoutParams).bottomMargin = (int) (Math.abs(position) * verticalInterval);
                llRoot.setLayoutParams(layoutParams);
            }
        }
        //设置偏移量----------------------------------------------------------------------
        if (position >= 0) {
            view.setTranslationX(-pagerWidth * position);
        }
        if (position > -1 && position < 0) {
            view.setAlpha((position * position * position + 1));
        } else if (position > offscreenPageLimit - 1) {
            view.setAlpha((float) (1 - position + Math.floor(position)));
        } else {
            view.setAlpha(1);
        }
    }
}

简洁明了,两个方法,即可实现。
好了,实现了交互,那么,还有一个“无限循环”的问题!
方案无非是两种,一种是adapter getCount设置为无限大,一种是通过前后补数据给用户做一个视觉差。但是具体到我们这里的实现,明显是第一种方法比较合适。这里也不过多叙述了。


最后,源码地址:代码地址
搜索VPTestActivity类

that’s all--------------------------------------------------------------------------------------------------

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/604294.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android系统安全技术---FBE密钥框架和技术详解

一、前言 用户数据加密是移动设备的重要功能&#xff0c;是使用对称加密算法对Android设备上的所有用户数据进行编码的过程&#xff0c;防止用户数据被未经授权的用户或应用程序访问。 本文是Android系统安全技术系列第二篇&#xff0c;主要介绍基于文件的加密技术。首先介绍An…

到底什么是“云手机”?

今天这篇文章&#xff0c;我们来聊一个很有趣的东东——云手机。 说到云手机&#xff0c;有些童鞋可能并不会觉得陌生。是的&#xff0c;它确实并不是一个新名词。早在2011年左右&#xff0c;国内就有厂商推出了云手机的概念。掐指一算&#xff0c;至今已经有12个年头了。 大家…

APP在应用市场内该如何做推广

苹果应用商城的自然流量都是通过精品推荐&#xff0c;畅销排行榜和搜索来获取的&#xff0c;此外&#xff0c;应用名称、副标题、应用截图视频、应用描述、用户评论、下载量、用户留存率还有曝光量&#xff0c;这些都是影响ASO优化的关键因素。 为了防止一些应用堆砌热词&…

传统设备充电接口如何升级成USB-C PD快充接口?

早在 2009 年开始&#xff0c;欧盟就致力于推动消费电子产品充电接口的统一进程&#xff0c;减少资源浪费推动绿色环保进程&#xff0c;同时充电配件通用化也为消费者带来更好的充电体验。2022 年 10 月 4 日&#xff0c;欧洲议会全体会议上表决通过&#xff0c;在 2024 年底之…

C++服务器框架开发8——日志系统LogFormatter_3/override/宏定义优化switchcase结构

该专栏记录了在学习一个开发项目的过程中遇到的疑惑和问题。 其教学视频见&#xff1a;[C高级教程]从零开始开发服务器框架(sylar) 上一篇&#xff1a;C服务器框架开发7——日志系统LogFormatter_2 C服务器框架开发8——日志系统LogFormatter_3/override/宏定义优化switchcase…

代码随想录算法训练营day60 | 84.柱状图中最大的矩形

代码随想录算法训练营day60 | 84.柱状图中最大的矩形 84.柱状图中最大的矩形解法一&#xff1a;单调栈解法二&#xff1a;暴力双指针(会超时)解法三:优化双指针 总结 最后一天打卡留念! 84.柱状图中最大的矩形 教程视频&#xff1a;https://www.bilibili.com/video/BV1Ns4y1o7…

国产化麒麟linux系统QtCreator和QtCreator编译的程序无法输入中文libfcitx最新版本编译1.2.7

1.问题描述 麒麟linux系统QtCreator和QtCreator编译的程序无法输入中文&#xff0c;网上找了很多的libfcitxplatforminputcontextplugin.so库都无法使用正常输入&#xff1b; Qt版本&#xff1a;5.9.6 麒麟系统版本&#xff1a;海光麒麟桌面版kylin V10 SP1 小版本号2203 X…

一个多功能(聚合)查询接口,实现模糊、分页、主键、排序以及多条件查询

一个多功能(聚合)查询接口&#xff0c;实现模糊、分页、主键、排序以及多条件查询 前言 写的啰嗦了点&#xff0c;看效果请直接忽略中间&#xff0c;直接看后半部分。 引个流&#xff0c;公众号&#xff1a;小简聊开发 概念 瞎编的名字&#xff0c;哈哈哈&#xff0c;我就勉强…

一道北大强基题背后的故事(二)——出题者怎么想的?

早点关注我&#xff0c;精彩不错过&#xff01; 上篇文章中&#xff0c;我们给出一道北大强基考试中的试题&#xff0c;计算[((1 sqrt(5)) / 2) ^ 12]&#xff0c;给出了一条没有任何数学直觉&#xff0c;纯硬算的弯路以及题目的参考答案&#xff0c;相关内容请戳&#xff1a;…

IronPDF 2023.6.10 FOR NET CRACK

适用于.NET的IronPDF 2023.6.10 添加新的注释API并改进图像压缩逻辑。 2023年6月2日-14:42新版 特点 添加了新的连续进给选项。例如用于生成收据文档。 添加了新的注释API&#xff0c;包括注释删除。 添加了删除书签的功能。 将内存使用率和性能提高了10%。 改进了图像…

全球加速AEB「强标」,15万元以下车型或将「释放」巨量需求

目前&#xff0c;智能驾驶技术升级&#xff0c;主要是在帮助中高端车型提升产品竞争力&#xff0c;同时为车企构建未来软件付费盈利模式的转型。 但另一方面&#xff0c;基础辅助驾驶&#xff0c;尤其主动安全&#xff0c;比如&#xff0c;AEB&#xff08;自动紧急制动&#xf…

【企业化架构部署】基于Apache搭建LAMP架构

文章目录 前言一、LMAP架构介绍1.概念2.LAMP构建顺序3.LAMP编译安装4.各组件介绍4.1 Linux4.2 Apache4.3 MySQL4.4 PHP/Perl/Python 二、服务器部署1.Apache部署2.MySQL部署3.PHP部署4.安装论坛 前言 LAMP架构是目前成熟的企业网站应用模式之一&#xff0c;指的是协同工作的一整…

考上大学,走进网安

出品&#xff5c;MS08067实验室&#xff08;www.ms08067.com&#xff09; 本文作者&#xff1a;北平靴 01 我和网络安全的相遇&#xff0c;说来很巧。2022年我考入吉林大学计算机学院&#xff0c;正巧我们的导助是学校ctf战队的成员&#xff0c;所以在刚入学的很清闲的日子里&a…

Python中logger模块的使用教程

参考模块&#xff1a; https://www.digitalocean.com/community/tutorials/how-to-use-logging-in-python-3 logger是python的内置模块&#xff0c;用以输出代码运行过程中的运行情况&#xff0c;极大的方便了我们的debug过程。参考资料中列出了使用logger相比于print优越的地方…

ResNet学习

目录 是什么作用怎么做论文阅读 视频来源&#xff1a;https://www.bilibili.com/video/BV1rZ4y1m7d9/?spm_id_from333.337.search-card.all.click&vd_sourcea402747bd6c153bdb2defee02a9cb617 https://www.bilibili.com/video/BV1rZ4y1m7d9/?spm_id_from333.788&vd_…

Java官方笔记5数字和字符串

Numbers Number的子类&#xff1a; 另外还有BigDecimal和BigInteger&#xff0c;用于高精度计算&#xff0c;AtomicInteger和AtomicLong用于多线程应用。 我们有时候需要用包装类而非基本数据类型&#xff0c;理由如下&#xff1a; 方法入参类型为Object&#xff0c;只能传入对…

什么是Linux shell

一句话概括&#xff1a;简单来说脚本就是将需要执行的命令保存到文本中&#xff0c;按照顺序执行&#xff08;由上往下执行&#xff09;&#xff0c;shell脚本:shell脚本就是一些命令的集合。 一、创建第一个Shell脚本&#xff1a;输出helloworld 1&#xff0e;脚本格式 脚本…

体验管理|“以旧换新”重塑“家电和耐用品”低频的消费需求

Guofu 第 96⭐️ 篇原创文章分享 &#xff08;点击&#x1f446;&#x1f3fb;上方卡片关注我&#xff0c;加⭐️星标⭐️~&#xff09; &#x1f68f; 写在前面 消费者越来越注重产品或服务的体验&#xff0c;而品牌也在竭力提供更好的体验来吸引和保留消费者。 &#x1f926;…

华为OD机试真题 Java 实现【火车进站】【牛客练习题】

一、题目描述 给定一个正整数N代表火车数量&#xff0c;0<N<10&#xff0c;接下来输入火车入站的序列&#xff0c;一共N辆火车&#xff0c;每辆火车以数字1-9编号&#xff0c;火车站只有一个方向进出&#xff0c;同时停靠在火车站的列车中&#xff0c;只有后进站的出站了…

基于SpringBoot+Vue的小区物业管理系统设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架下…