本文已授权微信公众号:鸿洋(hongyangAndroid)原创首发

《交互炸了》或许是一系列高端特效教程, 文中会介绍一些比较炫酷的特效,以及实现的思路。特效实现本身也许不会有太大的难度。难点在于实现的思路。一旦思路被打开,特效将很简单实现。

DragPhotoView项目地址https://github.com/githubwing/DragPhotoView

大家好,本期是交互炸了第四期~ 本期带来的效果是最新版微信朋友圈看图下拖的效果,没见过的赶紧去更新微信啦~~

本期跟以往不一样:

不是demo! 拿来直接用!不是demo! 拿来直接用!不是demo! 拿来直接用!重要说三你懂.

效果图如下:

自我感觉实现的效果还不错哈.猛地一看自己都以为他就是微信了哈哈.

一分钟使用方式:


修改你的 build.gradle文件


  1. //root project
  2. allprojects {
  3. repositories {
  4. ...
  5. maven { url 'https://jitpack.io' }
  6. }
  7. }
  8. //module project
  9. dependencies {
  10. compile 'com.github.githubwing:DragPhotoView:1.0.1'
  11. }

把它放到xml里

把它当成普通ImageView使用就行了,所有ImageView的玩法都可以在它身上玩.注意必须要加一个onExitListener,这是在拖拽出范围的监听.


  1. // 所有ImageView用法都可以
  2. DragPhotoView photoView = (DragPhotoView)findViewById(R.id.photoView);
  3. photoView.setImageResource(R.drawable.ram);
  4. //必须添加一个onExitListener,在拖拽到底部时触发.
  5. photoView.setOnExitListener()
  6. photoView.setOnTapListener()

这样就完成了接入,甚至比一分钟还快有没有!拒绝标题党.


上面讲解的是用法,可是用谁都会,使用一个三方库,都要了解实现对不? 下面就给大家介绍实现的思路.

实现

基于PhotoView

第一眼看到这个效果,就有想实现的冲动,因为使用场景挺多的感觉. 所以直接找来GitHub上star最多的PhotoView来进行扩展,这里我选择直接依赖并且继承PhotoView,理由是如果PhotoView出了更新,依赖直接改动版本即可.如果我选择源码copy的方式改动,那么将得不到PhotoView的支持.

图片缩放,背景透明

这里需要Activity配合,将背景设置为透明.并且背景实黑色的,为了配合手势改变View背景透明度,我绘制一个超大的矩形充当背景:

  1. @Override
  2. protected void onDraw(Canvas canvas) {
  3. mPaint.setAlpha(mAlpha);
  4. canvas.drawRect(0, 0, 2000, 2000, mPaint);
  5. canvas.translate(mTranslateX, mTranslateY);
  6. canvas.scale(mScale, mScale, mWidth / 2, mHeight / 2);
  7. super.onDraw(canvas);
  8. }

画布位移和缩放还有透明度都跟着手势变化而变化.所以要处理触摸事件,一开始我尝试重写onTouchEvent方法,发现并不生效,原因是PhotoView内部使用了自己的手势处理机制. 所以手势处理束手无策里吗? 非也,我们可以在dispatchTouchEvent做处理.所以重写该方法:

首先判断是否处于缩放模式,只有非缩放模式的时候才可以拖拽


  1. @Override
  2. public boolean dispatchTouchEvent(MotionEvent event) {
  3. if (getScale() == 1) {
  4. }
  5. }

之后处理ACTION_MOVE事件:

需要注意的是,要解决一下Viewpager和DragPhotoView和PhotoView的冲突.

DragPhotoView和PhotoView的冲突在于手势缩放,所以只要判断一下当前是几个触摸点即可.

下Viewpager和DragPhotoView冲突在左右滑,所以这里判断为:如果没有向下移动过,则Y位移为0交由ViewPager处理,如果向下移动过,则改变标志位说明正在处于拖拽状态

  1. case MotionEvent.ACTION_MOVE:
  2. //in viewpager
  3. if (mTranslateY == 0 && mTranslateX != 0) {
  4. //如果不消费事件,则不作操作
  5. if (!isTouchEvent) {
  6. mScale = 1;
  7. return super.dispatchTouchEvent(event);
  8. }
  9. }
  10. //single finger drag down
  11. if (mTranslateY >= 0 && event.getPointerCount() == 1) {
  12. onActionMove(event);
  13. //如果有上下位移 则不交给viewpager
  14. if (mTranslateY != 0) {
  15. isTouchEvent = true;
  16. }
  17. return true;
  18. }
  19. //防止下拉的时候双手缩放
  20. if (mTranslateY >= 0 && mScale < 0.95) {
  21. return true;
  22. }
  23. break;

在ACTION_UP的时候,要判断一下是否拖拽超过阀值,如果超过了阀值则进行结束Activity操作.

这里遇到个坑就是,单指返回和双击放大手势冲突了.目前没有找到什么好的解决方法,只能开启线程计时来根据标志位判断,各位看官有好的解决方式,请联系告知我,谢谢!

  1. case MotionEvent.ACTION_UP:
  2. //防止下拉的时候双手缩放
  3. if (event.getPointerCount() == 1) {
  4. onActionUp(event);
  5. isTouchEvent = false;
  6. //judge finish or not
  7. postDelayed(new Runnable() {
  8. @Override
  9. public void run() {
  10. if (mTranslateX == 0 && mTranslateY == 0 && canFinish) {
  11. if (mTapListener != null) {
  12. mTapListener.onTap(DragPhotoView.this);
  13. }
  14. }
  15. canFinish = false;
  16. }
  17. }, 300);
  18. }

这样基本上就完成了对PhotoView的扩展. 已经可以接入项目中使用了.

但是本文还没有完,下面说一下共享元素的全版本实现

Android自带的共享元素只有5.0以上才可以使用.那么怎么兼容到5.0以下呢.并且Demo中的拖拽共享是怎么实现的呢?

其实思路很简单,只需要在Activity A启动Activity B的时候,关闭系统专场动画,把被点击的View 大小,坐标等信息传入. B先为透明状态,把B上的View做一个位移动画,就可以实现了.

  1. public void startPhotoActivity(Context context, ImageView imageView) {
  2. Intent intent = new Intent(context, DragPhotoActivity.class);
  3. int location[] = new int[2];
  4. imageView.getLocationOnScreen(location);
  5. intent.putExtra("left", location[0]);
  6. intent.putExtra("top", location[1]);
  7. intent.putExtra("height", imageView.getHeight());
  8. intent.putExtra("width", imageView.getWidth());
  9. context.startActivity(intent);
  10. //关闭系统共享元素动画
  11. overridePendingTransition(0,0);
  12. }

至于拖拽共享元素,原理是一样的,具体的细节就在demo中啦~~

本文到此就结束啦~

DragPhotoView项目地址https://github.com/githubwing/DragPhotoView

如果你觉得不错,欢迎Star

也可以加入我的Android酒馆:425983695

这交互炸了(四) :一分钟让你拥有微信拖拽透明返回PhotoView的更多相关文章

  1. 这交互炸了:饿了么是怎么让Image变成详情页的

    这交互炸了:饿了么是怎么让Image变成详情页的 晚上叫外卖,打开饿了么,发现推了一个版本,更新以后,点开了个鸡腿,哇,交互炫炸了. 本文同步自wing的地方酒馆 不过还是有槽点.我是无意中才发现可以 ...

  2. Flutter交互实战-即刻App探索页下拉&拖拽效果

    前言 Flutter最近比较热门,但是Flutter成体系的文章并不多,前期避免不了踩坑:我这篇文章主要介绍如何使用Flutter实现一个比较复杂的手势交互,顺便分享一下我在使用Flutter过程中遇 ...

  3. 【干货】零基础30分钟让你拥有一个完整属于自己的短视频APP系统

      目录 一.附言: 1 二.购买域名和购买服务器: 2 三.搭建服务器环境: 5 四.配置APP前端部分: 8 1.工具以及文件准备: 9 2.配置后端接口地址 11 3.配置APP启动图和启动图标 ...

  4. javascript事件类型之界面拖拽交互

    一.在线DEMO 界面拖拽交互

  5. HTML5实战与剖析之原生拖拽(四可拖动dragable属性和其他成员)

    可拖动dragable属性 之前我们已经为大家介绍过几篇有关HTML5中原生拖拽的相关知识了.今天为大家介绍HTML5拖拽中的其他一些小东东,闲话不多说赶快一起看看吧. 在默认情况下,链接.文本和图像 ...

  6. GridView实现拖拽排序以及数据交互

    在研究项目中的一个效果的时候,查找资料过程中发现有人有这么一种需求,就是GridView在实现拖拽排序的基础上,如果是两个GridView之间实现拖拽效果,并要实现数据交互. 一.效果图: 实现这个效 ...

  7. Vue实现拖拽穿梭框功能四种方式

    一.使用原生js实现拖拽 点击打开视频讲解更加详细 <html lang="en"> <head> <meta charset="UTF-8 ...

  8. C++与Lua交互(四)

    引言 通过前几篇,我们已经对Lua的C API有了一定的了解,如lua_push*.lua_is*.lua_to*等等.用C++调用Lua数据时,我们主要运用lua_getglobal与lua_pus ...

  9. 四:MySQL系列之Python交互(四)

    该篇主要介绍MySQL数据库的分表.以及与Python的交互的基本操作等. 一.拆分表操作 1.1  准备工作 创建数据库 --> 使用数据库 --> 创建数据表 --- 添加记录 -- ...

随机推荐

  1. Java面试题—初级(4)

    31.String s = new String("xyz");创建了几个StringObject?是否可以继承String类? 两个或一个都有可能,"xyz" ...

  2. Tensorflow计算模型 —— 计算图

    转载自:http://blog.csdn.net/john_xyz/article/details/69053626 Tensorflow是一个通过计算图的形式来表述计算的编程系统,计算图也叫数据流图 ...

  3. Typescript学习

    一 什么是Typescript 简单的说,TypeScript 是 JavaScript 的一个超集,主要提供了类型系统和对 ES6 的支持,它由 Microsoft 开发,代码开源于 GitHub  ...

  4. springboot启动报错

    新建springboot整合aop记录web日志的过程中启动失败 错误如下: ***************************APPLICATION FAILED TO START******* ...

  5. Ubuntu 16下安装64位谷歌Chrome浏览器

    Ubuntu 16下安装64位谷歌Chrome浏览器 1.将下载源加入到系统的源列表 在终端中,输入以下命令: sudo wget https://repo.fdzh.org/chrome/googl ...

  6. 6.19 noip模拟题(题目及解析转自 hzwer 2014-3-15 NOIP模拟赛)

    Problem 1 高级打字机(type.cpp/c/pas) [题目描述] 早苗入手了最新的高级打字机.最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧. 请为这种高级打字机设计一个程序 ...

  7. [NOI2009]变换序列

    Description Input Output Sample Input 5 1 1 2 2 1 Sample Output 1 2 4 0 3 HINT 30%的数据中N≤50: 60%的数据中N ...

  8. Prison 监狱

    [题目描述]Caima 王国中有一个奇怪的监狱,这个监狱一共有 P 个牢房,这些牢房一字排开,第 i 个仅挨着第 i+1 个(最后一个除外).现在正好牢房是满的.上级下发了一个释放名单,要求每天释放名 ...

  9. [bzoj4820][Sdoi2017]硬币游戏

    来自FallDream的博客,未经允许,请勿转载,谢谢. 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数多谁胜利.大家纷纷觉得这个游戏非常符合同学们的特色,但只是扔硬币实在是太单调了 ...

  10. bzoj4710: [Jsoi2011]分特产 组合+容斥

    4710: [Jsoi2011]分特产 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 289  Solved: 198[Submit][Status] ...