利用RecyclerView打造炫酷滑动卡片

来源:互联网 发布:万户网络官网 编辑:程序博客网 时间:2024/06/11 23:51

今日科技快讯

近日,有报道称:掌上电力、电e宝App正在出现数据泄露,而且部分数据可能已经流入黑色产业链,危害持续扩大。掌上电力目前已在全国27个省(市、区)全面推广,用户接近9000万!

掌上电力开始面向消费者推广时,淘宝上就开始出现了大量提供“掌上电力绑定”服务的店铺,他们给各省电力公司提供关注、注册、绑定等服务,为各省的掌上电力迅速增加“用户量”。地方供电公司需要向淘宝店主提供消费者的客户编号、查询密码,部分店铺还要求提供详细地址!

目前国家电网在官微已经否认存在用户信息泄漏。并且淘宝的“掌上电力”APP、“电e宝”APP注册服务等已经无法检索。

作者简介

本篇来自 半栈工程师 的投稿,分享了一个炫酷的卡片滑动删除效果。希望大家喜欢。

半栈工程师 的博客地址:

http://www.jianshu.com/users/de53c0ce96ab

前言

前段时间一直在B站追《黑镜》第三季,相比前几季,这季很良心的拍了六集,着实过了一把瘾。由于看的是字幕组贡献的版本,每集开头都插了一个app的广告,叫“人人美剧”,一向喜欢看美剧的我便扫了一下二维码,安装了试一试。我打开app,匆匆滑动了一下首页的美剧列表,然后便随手切换到了订阅页面,然后,我就被订阅页面的动画效果吸引住了。

没错,就是上面这玩意儿,是不是很炫酷,本着发扬一名码农的职业精神,我心里便痒痒的想实现这种效果,当然因为长期的 fork compile,第一时间我还是上网搜了搜,有木有哪位好心人已经开源了类似的控件。借助强大的Google,我马上搜到了一个项目

SwipeCards

https://github.com/Diolor/Swipecards

是仿照探探的老父亲Tinder的app动画效果打造的,果然程序员都一个操行,看到好看的就想动手实现,不过人家的成绩让我可望而不可及~

他实现的效果是这样的:

嗯,还不错,为了进行思想上的碰撞,我就download了一下他的源码,稍稍read了一下~_~

作为一个有思想,有抱负的程序员,怎么能满足于compile别人的库呢?必须得自己动手,丰衣足食啊!

思考

一般这种View都是自定义的,然后重写 onLayout,但是有木有更简单的方法呢?由于项目里一直使用 RecyclerView,那么能不能用 RecyclerView 来实现这种效果呢?能,当然能啊!得力于 RecyclerView 优雅的扩展性,我们完全可以自定义一个 LayoutManager 来实现嘛。

布局实现

RecyclerView 可以通过自定义 LayoutManager 来实现各种布局,官方自己提供了LinearLayoutManager、GridLayoutManager,相比于 ListView,可谓是方便了不少。同样,我们也可以通过自定义 LayoutManager,实现这种View一层层叠加的效果。

自定义 LayoutManager,最重要的是要重写 onLayoutChildren()

这种布局实现起来其实相当简单,因为每个child的 left 和 top 都一样,直接设置为0就可以了,这样child就依次叠加在一起了,至于最后两句,主要是为了使 顶部Child 之下的childs有一种缩放的效果。

动画实现

下面到了最重要的地方了,主要分为以下几个部分。

1. 手势追踪

当手指按下时,我们需要取到 RecyclerView 的 顶部Child,并让其跟随手指滑动。

手指按下的时候,记录 topChildView 的位置,移动的时候,根据偏移量,动态调整 topChildView 的位置,就实现了基本效果。但是这样还不够,记得我们在实现布局时,对其他子View进行了缩放吗?那时候的缩放是为现在做准备的。当手指在屏幕上滑动时,我们同样会调用 updateNextItem(),对 topChildView 下面的 子view 进行缩放。

这里的 factor 计算很简单,只要当 topChildView 滑动到设置的边界时,nextView 刚好缩放到原本大小,即 factor=1,就可以了。因为 nextView 一开始缩放为 0.8,所以可计算出:

factor=Math.abs(topView.getX() - mTopViewX) * 0.2 / mBorder + 0.8

2. 抬起手指

手指抬起后,我们要进行状态判断

(1). 滑动未超过边界

此时我们需要对 topChildView 进行归位。

(2). 超过边界

此时我们需要根据滑动方向,使 topChildView 飞离屏幕。

对于这两种情况,我们都是通过计算view的终点坐标,然后利用动画实现的。对于第一种,很简单,targetX 和 targetY 直接就是 topChildView 的原始坐标。但是对于第二种,需要根据 topChildView 的原始坐标和目前坐标,计算出线性表达式,然后再根据 targetX 来计算 targetY,至于 targetX,往右飞 targetX 就可以赋为 getScreenWidth,而往左就直接为 0-view.width,只要终点在屏幕外就可以。具体代码如下:

对于第二种情况,如果直接启动动画,并在动画结束时通知 adapter 删除item,在连续操作时,会导致数据错乱。但是如果在动画启动时直接移除item,又会失去动画效果。

所以我在这里采用了另一种办法,在动画开始前创建一个与 topChildView 一模一样的 镜像View,添加到 DecorView 上,并隐藏删除掉 topChildView,然后利用镜像View来展示动画。添加镜像View的代码如下:

因为 镜像View 是添加在 DecorView 上的,topChildView 父容器是 RecyclerVIew,而View的x、y是相对于父容器而言的,所以 镜像View 的 targetX 和 targetY 需要加上一定偏移量。

好了到这里,一切就准备就绪了,下面让我们看看动画效果如何:

总结

效果是不是还不错,项目地址在这里:

https://github.com/HalfStackDeveloper/SwipeCardRecyclerView

欢迎大家 fork AND star!也希望大家在使用app,看到一些酷炫效果的时候,也自己去动手实现,谁让我们是有着职业精神的码农呢!

更多

每天学习累了,看些搞笑的段子放松一下吧。关注最具娱乐精神的公众号,每天都有好心情。

如果你有好的技术文章想和大家分享,欢迎向我的公众号投稿,投稿具体细节请在公众号主页点击“投稿”菜单查看。

欢迎长按下图 -> 识别图中二维码或者扫一扫关注我的公众号: