前言

最近有个需求,要做成今日头条的效果,我就下载了今日头条的app看了看,发现效果简单,体验也还不错,最近几天发现QQ空间安卓版也有这个效果,当然,牛逼的微信早就有这个效果了,而且微信的图片随着手势下拉是图片会缩放的并且有入场和退出的动画,交互比头条和QQ的多了两个动画,其实我觉得交互越简单对于用户来说越好,我反而觉得头条和QQ空间的效果不错,所以今天就来实现下今日头条的这个效果.

今日头条和QQ空间的效果图

  

我最终实现的效果图

 

需求分析

思考一下,其实不难,总共就没有几个动画,我是在项目用的缩放控件上改的,这样项目改动最小,这样改一个类所有涉及到的类就全都改了.
1.可以看到头条点击图片时首先有淡入淡出的动画,这个就用overridePendingTransition 转场动画就行,安卓2.0以上就支持,在startActivity() 或者 finish后面加上转场动画 fade_in,fade_out,淡入淡出的效果就实现了.
2.头条和QQ空间的大图浏览时,双手放大时是不会拖动该图片的,因此,当图片没有被放大时,同时只有一个手指才会触发上下拖动这个事件.
3.可以看到上下拖动状态时,背景透明度跟着改变,首先大图浏览模式下的类Activity必须是透明的主题,这个效果才能实现,即把配置文件中把Activity的主题使用透明的主题即可.
4.手势拖动使用ViewHelper类,即操作View动画类的方法集合,gradle里面远程依赖com.nineoldandroids:library:2.4.0 即可.

核心代码

根据上述的分析,我想大家都跃跃欲试了,其实真的不难,最好都代码编写下,给自己的项目也加个效果.

1.首先要让当前View动起来

 根据上面的分析,用到了ViewHelper.其上下拖动的触发条件是 当前的scale 没有放大,同时fingerTouch = 1即一个手指的情况下,触发拖动的事件.if(currentScale <= minscale() && touchCount == 1) ----> onSingleActionMove(event);

2.onSingleActionMove方法

这里边主要是透明度的算法,透明度是从0到1,view移动的范围是MAX_TRANSLATE_Y 这里透明度的计算我又加上了图片高度,防止透明度的跨度过大,View的移动距离[0,MAX_TRANSLATE].
则百分比 percent = 移动的距离(mTranslateY) / MAX_TRANSLATE_Y;
同理 alpha 透明度的范围是[1,0],即从不透明到透明的过程,则变量为 mAlpha = 1 - percent;
则代码编写如下:
private void onSingleActionMove(MotionEvent event) {isOneFingerDrag = true;float moveX = event.getRawX();float moveY = event.getRawY();mTranslationX = moveX - mDownX + mLastTranslationX;mTranslationY = moveY - mDownY + mLastTranslationY;float percent = Math.abs(mTranslationY / (MAX_TRANSLATE_Y + sHeight));Log.e(TAG, "percent= " + percent + "translationY= " + mTranslationY + "Max_Y = " + MAX_TRANSLATE_Y);LinearLayout linearLayout = (LinearLayout) getParent();float mAlpha = (1 - percent);if (mAlpha > 1) {mAlpha = 1;} else if (mAlpha < 0) {mAlpha = 0;}Log.e(TAG, "alpha = " + mAlpha);if (null != linearLayout) {linearLayout.getBackground().mutate().setAlpha((int) (mAlpha * 255));}ViewHelper.setTranslationY(this, mTranslationY);}

3.callBack 回归原位的动画方法

当移动距离mTranslateionY 小于 可退出的最大值时,则让其回归原位,其移动范围为[mTransltionY,0]
使用ValueAnimator 线性回归,编写代码如下:
private void resetCallBackAnimation() {ValueAnimator animatorY = ValueAnimator.ofFloat(mTranslationY, 0);animatorY.setDuration(DURATION);animatorY.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator valueAnimator) {if (isAnimate) {mTranslationY = (float) valueAnimator.getAnimatedValue();mLastTranslationY = mTranslationY;ViewHelper.setTranslationY(SubsamplingScaleImageView2.this, mTranslationY);}}});animatorY.addListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animation) {isAnimate = true;}@Overridepublic void onAnimationEnd(Animator animation) {if (isAnimate) {mTranslationY = 0;LinearLayout linearLayout = (LinearLayout) getParent();if (null != linearLayout) {linearLayout.getBackground().mutate().setAlpha(255);}invalidate();reset();}isAnimate = false;}@Overridepublic void onAnimationCancel(Animator animation) {}@Overridepublic void onAnimationRepeat(Animator animation) {}});animatorY.start();}

4.退出并关闭当前界面动画

  当mTranslationY > MAX_TRANSLATE_Y 时 则从当前位置退出,它的运动轨迹为[mTranslationY,getHeight()]
当向上滑动退出时,mTranslationY 为负值,则其运动轨迹为[mTranslationY,-getHeight()]; 
使用的均是ValueAnimator动画退出.
public void exitWithTranslation(float currentY) {float translationY;float imgHeight = sHeight;if (currentY > 0) {ValueAnimator animDown = ValueAnimator.ofFloat(mTranslationY, getHeight());animDown.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {float fraction = (float) animation.getAnimatedValue();Log.e(TAG, "fraction==" + fraction);ViewHelper.setTranslationY(SubsamplingScaleImageView2.this, fraction);}});animDown.addListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animation) {}@Overridepublic void onAnimationEnd(Animator animation) {reset();((Activity) getContext()).finish();((Activity) getContext()).overridePendingTransition(0, 0);}@Overridepublic void onAnimationCancel(Animator animation) {}@Overridepublic void onAnimationRepeat(Animator animation) {}});animDown.setDuration(DURATION);animDown.setInterpolator(new LinearInterpolator());animDown.start();} else {ValueAnimator animUp = ValueAnimator.ofFloat(mTranslationY, -getHeight());animUp.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {float fraction = (float) animation.getAnimatedValue();Log.e(TAG, "fraction==" + fraction);ViewHelper.setTranslationY(SubsamplingScaleImageView2.this, fraction);}});animUp.addListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animation) {}@Overridepublic void onAnimationEnd(Animator animation) {reset();((Activity) getContext()).finish();((Activity) getContext()).overridePendingTransition(0, 0);}@Overridepublic void onAnimationCancel(Animator animation) {}@Overridepublic void onAnimationRepeat(Animator animation) {}});animUp.setDuration(DURATION);animUp.setInterpolator(new LinearInterpolator());animUp.start();}}

遇到的坑

透明度改变时,当前View的透明度跟着变化,让人头疼的问题.
使用下面代码解决,让其不共享透明度的变化.
 linearLayout.getBackground().mutate().setAlpha(255);
2018.01.18更新
1.使用setScrollY替代setTranslateY优化动画体验.
2.增加仿微信朋友圈下拉的动画效果.

源码下载
欢迎star 和 fork,谢谢!

Android高仿今日头条/QQ空间手势下拉关闭图片效果相关推荐

  1. android 仿写开发者头条,android高仿今日头条富文本编辑(发布文章)

    前言: 在经历了几个月的项目期限.我们遇到了前端发布文章,要用到富文本编辑的功能.在一番衡量下最终用到了richeditor-android第三方框架.实现原理就是通过webView和js实现前端富文 ...

  2. android高仿今日头条 --新闻阅读器

    摘要: 开发流程 第一篇:(android高仿系列)今日头条 --新闻阅读器 (一) 涉及到的知识点有 1.slidingmenu.lib  (侧拉菜单包)   使用方法配置以及下载:点击这里   实 ...

  3. android高仿今日头条小视频转场切换效果

    可以先看看今日头条效果 功能分析 点击列表上的一个item,该item会放大,最后直接全屏播放小视频,刚开始看上去,以为是个共享元素的转场动画, 后来想到,共享元素要在android 5.0以上支持, ...

  4. android高仿今日头条,高仿今日头条App

    采用了MVVM + RAC的方式,对微头条界面 使用YYCache 进行了本地缓存 效果跟目前最新的今日头条有些地方不一样,因为今日头条最近更新了新版本 下面对项目中的一些效果和实现思路做下介绍 如果 ...

  5. android 上下滚动文字_android高仿今日头条富文本编辑(发布文章)

    前言 在经历了几个月的项目期限.我们遇到了前端发布文章,要用到富文本编辑的功能.在一番衡量下最终用到了[richeditor-android](https://github.com/wasabeef/ ...

  6. android 今日头条加载动画,高仿今日头条加载动画

    01 每每浏览手机app时,发现有的效果体验不错,作为一位程序员,总想要是自己来做,怎么实现. 今天我们来模仿今日头条的加载动画. 首先我们来看一下我们这个demo最终效果,有图有真相. 高仿今日头条 ...

  7. android如何展示富文本_android高仿今日头条富文本编辑(发布文章)

    前言: 在经历了几个月的项目期限.我们遇到了前端发布文章,要用到富文本编辑的功能.在一番衡量下最终用到了richeditor-android第三方框架.实现原理就是通过webView和js实现前端富文 ...

  8. Android 仿今日头条评论时键盘自动弹出的效果

    Android 仿今日头条评论时键盘自动弹出的效果:当点击评论时,弹出对话框,同时弹出软键盘,当点击返回键时,将对话框关闭,不只是关闭软键盘. 效果图: 对这个对话框设置一个style效果: < ...

  9. IOS每日精选源码,边缘识别导航条管理高仿今日头条语音查询汇率源码

    CIDetector边缘识别 超级简单的导航条管理工具EasyNavigation navigationbar 高仿今日头条频道选择弹框 iOS一个比较实用的侧边栏管理器 联动tableView,菜单 ...

  10. Android 仿今日头条频道管理(下)(GridView之间Item的移动和拖拽)

    前言 上篇博客我们说到了今日头条频道管理的操作交互体验,我也介绍了2个GridView之间Item的相互移动.详情请參考:Android 仿今日头条频道管理(上)(GridView之间Item的移动和 ...

最新文章

  1. Ubuntu 11.10中用xen-tools安装虚拟机(UbuntuCentOS)
  2. centos7 yum源_搭建内网Linux CentOS yum源,摆脱依赖包困扰
  3. android按钮最底,Android:点击按钮后布局上的动画,最低SDK版本为14
  4. 全国高等学校计算机等级考试(江西考区)一级笔试试卷a,全国高等学校计算机等级考试(江西考区)一级笔试试卷A...
  5. 15、java中的集合(2)
  6. html4废弃了哪些元素,HTML中的一些废弃元素_html
  7. Apache工具包方法——Hex.encodeHexString(byte[] data)源码浅析
  8. 20行Python代码检测人脸是否佩戴口罩
  9. 怎么实现两周联动加减速_LOL:野辅联动成版本主旋律,三大辅助对线游走兼备...
  10. mysql mha reference_MySQL MHA配置常见问题
  11. docker 重启gitlab_gitlab从入门到绝望
  12. http://www.myeclipseide.com/ 官网打不开的问题!myeclipse 官网!
  13. 企业微信api,企业微信sdk接口
  14. 小觅深度相机标准版 ROS使用
  15. Windows 10 error code 0x80072efd
  16. 命令行压缩工具7z.exe使用详解
  17. 从一杯果汁浅谈点点医生充值提现模块设计
  18. 新手常见(五国)(-v图)错误解决(原版,破解kernel,补丁kext下载)
  19. Windows下批量删除空文件夹
  20. 研发人员为什么留不住:问题与现象、原因的解析

热门文章

  1. CYQ.Data V5 分布式自动化缓存设计介绍
  2. Vue进阶(四十七):面试必备:2022 Vue经典面试题总结(含答案)
  3. 深度学习实战7-电商产品评论的情感分析
  4. mini LED光学仿真
  5. 【动态规划】 EditDistance
  6. java opencv 基本操作4
  7. Android 自动点击工具,安卓自动点击器免费版
  8. nrr评分预测_NRR的完整形式是什么?
  9. 【AI模型部署】maskrcnn在tfserver部署以及调用时遇到问题:Servable not found for request “xx”、‘incompatible_shape_error‘
  10. 前端 - token 是什么?为什么每次请求头(HEADS)里要携带它?