这交互炸了:饿了么是怎么让Image变成详情页的
本文由旋转跳跃就团灭的wing投稿。
旋转跳跃就团灭的wing的博客地址:
昨天有个大喜事,我觉得大家都知道了吧~~不知道的输入下面这个网址就懂了:
晚上叫外卖,打开饿了么,发现推了一个版本,更新以后,点开了个鸡腿,哇,交互炫炸了。
不过还是有槽点。我是无意中才发现可以左右滑动的。这。。。你不告诉我,我怎么知道左右可以滑。
https://github.com/githubwing/ZoomHeader
直接上图啊:
挺有意思的,对吧? 所以我就想模仿一下。下面是我做出来的效果:
额。。不过图片不是长条的哈。大概意思一样就行了。接下来将和大家分享这个效果是如何实现的。讲思路以及遇到的问题。但是不会讨论细节,具体的细节请看源码。
他是一个Activity还是两个?
相信你肯定有这样的疑问,答案是一个。
你看到的中间imageview是viewpager。在Viewpager上面是一个透明的View。当然,这个Activity的背景也是透明的。
1 实现思路
我使用CoordinatorLayout+Behavior实现的。说实话,Behavior真心强大。。
viewpager+头部
整个实现的思路是这样的。整体布局从上到下依次是:
-
透明View
-
viewpager
- RecyclerView
其中透明View和Viewpager 合并成一个自定义的Header。当这个Header上移的时候,图片放大,并且RecyclerView联动上衣,从透明转向并且不透明。
所以首先要定制一个透明的可移动的HeaderView。
在onTouchEvent处理一下手势。。
将header分为三种状态:
-
上移。则展开为详情页。
-
下移,则恢复为viewpager。
- 再下移,则finish Activity。
在上移的过程中,遇到了一点小挑战,这里分享下:
上移的过程中,图片需要放大。但是在做的过程中,不能使用LayoutParams实现。这里就关系到一些动画的小细节。
动画使用LayoutParams实现是一个禁忌。他会导致不停requestLayout,从而影响UI性能。
所以这里我的一个解法就是,我放大图片,不是真正的改变ImageView大小,而是去Scale图片。即使看起来变大了,他的View真正大小也不会变。
所以,有一句话叫做真亦是假、假亦是真 真真假假,你又何必当真呢?动画效果只要遵循这句话,基本上都是可以实现的。你所看到的效果都是假的。都是障眼法。View变大不是真正的变大。View悬浮不是真正的悬浮(有可能是显隐)。就像变魔术一样。。其实很简单。
接下来又遇到问题了。图片放大了,文字如何对齐? 文字的位置当然也不能真正改变。所以这里使用TranslationX实现。在图片放大的过程中,使用scale的系数,与两个端点值进行一个线性变化计算。主要文字对齐代码如下:
第二个点。就是在图片放大过程中,底部文字和按钮左右padding不能变。这也是我没有封装成一个拿来就用的View的原因(其实还是水平不够)。因为这些空间需要全部按照上方的方法进行动态计算。。所以也是比较坑爹的。。
2 ViewPager
拿了网上一个画廊的效果。直接
setPageTransformer(true, new ZoomOutPageTransformer());
这里注意,需要改变一下view的绘制顺序,保证当前view是最后绘制处于最上层
3 RecyclerView
RecyclerView最开始是完全透明的。并且跟随HeaderView上移而上移,在上移的过程中渐渐显示出来。 需要监听RecyclerView滚动,当RecyclerView滚动到顶部的时候。告知Header,该恢复最初原样了。
4 Behavior
让header和RecyclerView关联起来的就是Behavior了。Behavior之前写过几篇介绍过了,这里就不再啰嗦。
denpendcy为HeaderView。并且监听RecyclerView的滑动。
具体的细节还是看源码吧~
如果你觉得还不错,欢迎Star
阅读原文
- Adb连接模拟器出现版本错误
- .NET 云原生架构师训练营(模块二 基础巩固 EF Core 介绍)--学习笔记
- 设计模式--->静态代理模式
- 07.1 迭代器、生成器
- wildfly 21中应用程序的部署
- AI产品经理的入门必修课(4)——知识图谱
- 框架VS架构,看两者异同
- 使用WTM框架创建博客系统后台并在云服务器发布
- 06.1 __new__ 和 __init__区别
- MySQL必会的SQL查询语句优化方法你竟然还不知道!
- [系列] Go - 统一定义 API 错误码
- [系列] Go - time.RFC3339 时间格式化
- [系列] Go - 学习 grpc.Dial(target string, opts …DialOption) 的写法
- [系列] Go - 结构(struct) 实现 接口(interface)
- 聊两句XSS(跨站脚本攻击)
- 如何用Eggjs从零开始开发一个项目(3)
- 05.1 垃圾回收机制
- 服务器挂掉导致需要对k8s新增节点
- 【老李瞎折腾】003、安装docker环境
- ConcurrentHashMap线程安全吗?