专栏名称: 郭霖
Android技术分享平台,每天都有优质技术文章推送。你还可以向公众号投稿,将自己总结的技术心得分享给大家。
目录
相关文章推荐
郭霖  ·  Android振动分析:从App层到HAL层 ·  2 天前  
郭霖  ·  Android音视频基础能力之音频路由 ·  3 天前  
鸿洋  ·  一波深入的Android 性能优化 ·  3 天前  
郭霖  ·  这可能是Android软键盘监听的最佳方案 ·  5 天前  
郭霖  ·  activityGuard:Android ... ·  4 天前  
51好读  ›  专栏  ›  郭霖

仿豌豆荚应用列表进入详情效果

郭霖  · 公众号  · android  · 2017-01-13 08:00

正文

今日科技快讯

昨日腾讯QQ宣称,今年春节红包将会从小年持续到除夕,并会推出“LBS+AR天降红包”、“刷一刷红包”和“面对面”红包三大玩法。另外活动期间,会有多个当红明星与知名品牌派发2.5亿现金红包和价值30亿的卡券礼包。另一方面,微信已宣布:不会参加2017年春节红包大战。这意味着,今年红包大战QQ肩上的担子更重了,将要独自迎战阿里的两个参赛选手:一个是支付宝,还有一个是阿里持股的新浪微博。

作者简介

今天是周五啦,提前祝大家周末愉快!本篇来自 伪文艺大叔 的投稿,自己动手实现豌豆荚应用详情列表。我自己对比了下原版,几乎是高度还原。感兴趣的朋友赶快看看吧!

伪文艺大叔 的博客地址:

http://www.jianshu.com/u/030d732a71d2

前言

前两天买了个Android手机(ps:之前一直使用IPhone手机)打算给手机下载个应用市场,自己挺喜欢豌豆荚的,就下了个豌豆荚,在豌豆荚里下载App的时候发现它的列表进入详情效果挺好玩的,就想试试自己模仿一下。效果如下:

思路

当初看到这个效果的时候就在想列表界面和详情界面是一个 Activity + dialog 还是两个Activity,后来想了想详情界面数据挺多的应该不大可能是一个Activity,应该是一个列表Activity,一个详情Activity,那么针对这个设计就会有很多问题需要解决:

  • 跳转的时候如何无缝实现点击的 Item View 显示在详情Activity里是同一个位置呢?

  • 跳转成功以后如何还可以看到前面 Activit y的内容呢?

  • 如何让被点击的 Item View 慢慢的变化成详情页呢?

  • 详情 View 下拉出屏幕的时候如何退出详情 Activity?

  • 下拉的时候如何动态的改变背景色透明度呢?

带着这些问题我们来一个一个分析解决。

实现

  • 跳转的时候如何无缝实现点击的 Item View 显示在详情Activity里是同一个位置呢?

我们知道 View 在布局完成以后会有一个距离 父类View 顶部的属性 top,那么在两个 Activity 中把 View 距离顶部的高度 top 设成一致就可以了,然后在跳转的时候去掉跳转动画就可以实现视觉上的无缝连接,下面我们来看看具体代码:


view 就是当前被点击的 Item View,view.getTop() 就是 Item View 距离 RecyclerView 顶部的高度,getResources().getDimensionPixelOffset(R.dimen.bar_view_height) 是 RecyclerView 上面 Title View 的高度,因为我是隐藏了状态栏,所有 viewMarginTop 就是当前被点击的 Item View 距离状态栏顶部的高度;overridePendingTransition(0, 0) 就是去掉跳转动画实现视觉无缝隙, 详情 Activity 如何显示会在下面分析。

  • 跳转成功以后如何还可以看到前面Activity的内容呢?

其实就是把 详情Activity 背景设置成透明,并且把 详情View 的 父类View 背景都设置成透明就可以了,下面请看代码实现就是给 Activity 设置了一个透明的 Theme


  • 如何让被点击的 Item View 慢慢的变化成详情页呢?

跳转到详情页以后要显示列表页被点击的 Item View,设置它距离顶部的高度


mViewMarginTop 就是从列表界面传递过来的参数,mSVRootLl 就是 ScrollView 下面的 根LinearLayout,因为详情页面是可以滚动的,所以需要 ScrollView,设置好高度以后,调用 requestLayout 方法发起布局,在 onLayout 方法设置布局高度即可。


mContentMarginTop 就是刚才设置的高度,mTouchMoveOffset 默认是 0,  mIsAnimation 默认是 falsemIsLayoutImageView 默认是 false,这些参数的意义后面会分析到,这样 View 的高度就和列表界面被点击的 Item View 高度一样了,接下来分析被点击的 Item View 如何变化成详情页。

被点击的 Item View 到 详情Activity 以后就变成了一个 LinearLayout 布局,这个布局分为三部分: title布局中间布局bottom布局默认title和bottom是隐藏的,所以默认情况下的效果就是列表界面被点击 Item View 的效果,这个 View 显示出来以后马上通过一个动画变成详情界面,就是上面动画完成以后的效果,下面我们来看看动画的逻辑代码:


可以看到在 onAnimationUpdate 这个方法中根据 ratio 计算4个偏移量,这4个偏移量有啥用呢?从动画中可以看到被点击的 Item View 通过动画变成了一个 详情View,这个变化的过程包括4部分:

1:Item View 的上边距离顶部越来越近

2:Item View 下边距离底部越来越近

3:Item View 中的图片会慢慢居中

4:Item View 中的图片会慢慢向下靠近(如果不向下靠近,动画结束以后显示title布局,图片会有向下闪跃的问题)

那么这4部分移动的总距离乘以 ratio 就是动画执行过程中每次的偏移量,然后不断设置偏移量调用 requestLayout 方法发起布局来使 View 达到动画的效果;

上面说到的 mIsAnimation 这个字段这个时候就是 true 了, mIsLayoutImageView 也就是 true 了,只有执行动画的时候才会重新布局图片控件,动画结束以后会显示 title布局 和 bottom布局.

  • 详情View下拉出屏幕的时候如何退出详情Activity?

从效果中可以看到下拉的高度超过一半就匀速向下滑动,滑出屏幕关闭 Activity,小于一半就回弹到原来状态,这个功能需要用到事件分发原理。

当 ScrollView Y轴 滚动为0并且是向下拉的时候就会触发View滑动这个事件,通过 ACTION_DOWN 记录初始点,ACTION_MOVE 得到当前点,当前点减初始点得到滑动的距离(就是上面的 mTouchMoveOffset 变量),然后请求 requestLayout 方法发起布局调用 onLayout 方法刷新界面,手指松开的时候,判断滑动的距离是否超过一半,根据不同的状态通过动画改变 mTouchMoveOffset 的数值来刷新界面,下面来看看手势滑动和松开以后动画执行的代码:



动画执行完后调用回调方法关闭详情Activity:


  • 下拉的时候如何动态的改变背景色透明度呢?

通过代码可以看到在手势滑动的时候和动画的时候都调用了 updateBgColor 方法:


这个方法里的 mOnUpdateBgColorListener 是 详情Activity 设置的,通过调用 onUpdate 方法来改变背景的颜色透明度:


结束语

到此为止,项目里的逻辑和代码都分析完了,通过文章我们可以得出在开发一个功能的时候,首先要有大致的思路,想如何去实现这个功能,然后把思路中的问题一一破解,最后串联起来就可以了,谢谢大家的阅读,有想看源码的可以移步 github 地址:

https://github.com/chenpengfei88/WdjAppDetail

更多

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

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

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