这交互炸了:一分钟让你拥有微信拖拽透明返回photoview(代码片段)

三精-大精wing 三精-大精wing     2022-12-13     352

关键词:

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

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

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

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

本期跟以往不一样:

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

效果图如下:

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

一分钟使用方式:


修改你的 build.gradle文件


//root project
allprojects 
        repositories 
            ...
            maven  url 'https://jitpack.io' 
        
    

//module project
        dependencies 
            compile 'com.github.githubwing:DragPhotoView:1.0.1'
    

把它放到xml里

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


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

    photoView.setOnTapListener()

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


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

实现

基于PhotoView

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

图片缩放,背景透明

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

  @Override
    protected void onDraw(Canvas canvas) 
        mPaint.setAlpha(mAlpha);
        canvas.drawRect(0, 0, 2000, 2000, mPaint);
        canvas.translate(mTranslateX, mTranslateY);
        canvas.scale(mScale, mScale, mWidth / 2, mHeight / 2);
        super.onDraw(canvas);
    

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

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


    @Override
    public boolean dispatchTouchEvent(MotionEvent event) 
        if (getScale() == 1) 
        
    

之后处理ACTION_MOVE事件:
需要注意的是,要解决一下Viewpager和DragPhotoView和PhotoView的冲突.

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

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

     case MotionEvent.ACTION_MOVE:

                    //in viewpager
                    if (mTranslateY == 0 && mTranslateX != 0) 

                        //如果不消费事件,则不作操作
                        if (!isTouchEvent) 
                            mScale = 1;
                            return super.dispatchTouchEvent(event);
                        
                    

                    //single finger drag  down
                    if (mTranslateY >= 0 && event.getPointerCount() == 1) 
                        onActionMove(event);

                        //如果有上下位移 则不交给viewpager
                        if (mTranslateY != 0) 
                            isTouchEvent = true;
                        
                        return true;
                    


                    //防止下拉的时候双手缩放
                    if (mTranslateY >= 0 && mScale < 0.95) 
                        return true;
                    
                    break;

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

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

case MotionEvent.ACTION_UP:
                    //防止下拉的时候双手缩放
                    if (event.getPointerCount() == 1) 
                        onActionUp(event);
                        isTouchEvent = false;
                        //judge finish or not
                        postDelayed(new Runnable() 
                            @Override
                            public void run() 
                                if (mTranslateX == 0 && mTranslateY == 0 && canFinish) 

                                    if (mTapListener != null) 
                                        mTapListener.onTap(DragPhotoView.this);
                                    
                                
                                canFinish = false;
                            
                        , 300);
                    

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

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

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

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

 public  void startPhotoActivity(Context context, ImageView imageView) 
    Intent intent = new Intent(context, DragPhotoActivity.class);
    int location[] = new int[2];

    imageView.getLocationOnScreen(location);
    intent.putExtra("left", location[0]);
    intent.putExtra("top", location[1]);
    intent.putExtra("height", imageView.getHeight());
    intent.putExtra("width", imageView.getWidth());

    context.startActivity(intent);

    //关闭系统共享元素动画
    overridePendingTransition(0,0);
  

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

本文到此就结束啦~

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

如果你觉得不错,欢迎Star
也可以加入我的Android酒馆:425983695

这交互炸了:闪屏页是像云一样消失的(代码片段)

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

这交互炸了:爱范儿是如何让详情页缩小为横向列表的

...泪继续往下看。本开源库链接ExpandableViewpager一直想写《交互炸了》第二篇,但是好像没什么好的交互。就在昨晚11点,小马同学提出爱范儿里面的交互挺炸的。我一下,果然很赞。于是连夜写代码,封装成库,再撸文章。只为在... 查看详情

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

  目录一、附言: 1二、购买域名和购买服务器: 2三、搭建服务器环境: 5四、配置APP前端部分: 81.工具以及文件准备: 92.配置后端接口地址 113.配置APP启动图和启动图标 12五、搭建APP后端部分 13步骤,一步步输入并且... 查看详情

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

...么,发现推了一个版本,更新以后,点开了个鸡腿,哇,交互炫炸了。不过还是有槽点。我是无意中才发现可以左右滑动的。这。。。你不告诉我,我怎么知道左右可以滑。https://github.com/githubwing/ZoomHeader直接上图啊:挺有意思... 查看详情

springboot返回xml数据,一分钟搞定!

...贴了,可以点击查看之前分享的SpringBoot返回JSON数据,一分钟搞定!。你所需具备的基础什么是SpringBoot?SpringBoot核心配置文件详解SpringBoot开启的2种方式SpringBoot自动配置原理、实战SpringBoot2.x启动全过程源码分析更多请在Java技术... 查看详情

五分钟让你了解rpc原理详解(代码片段)

RPC功能目标RPC的主要功能目标是让构建分布式计算(应用)更容易,在提供强大的远程调用能力时不损失本地调用的语义简洁性。?为实现该目标,RPC框架需提供一种透明调用机制让使用者不必显式的区分本地调用和远程调用。... 查看详情

十分钟让你的javascript登峰造极

javascipt被称作前端的灵魂,没法灵活运用它,你的前端就只是一具行死走肉。大多初学者能顺利度过div+css,然后倒在了js怀抱,即时跨过了这一关,也只是会用,其底层原理一概不知。小编这就带大家从最底层的原理讲起,相信... 查看详情

分分钟让你理解https(代码片段)

一、HTTP存在的问题1.1可能被窃听HTTP本身不具备加密的功能,HTTP报文使用明文方式发送由于互联网是由联通世界各个地方的网络设施组成,所有发送和接收经过某些设备的数据都可能被截获或窥视。(例如大家都熟悉的抓包工具:Wires... 查看详情

这5款软件,让你的电脑变得更高效!

...又好用的软件。相信可以满足大家的很多需求,直接让你爱不释手!一、Convertio-文件转换器Convertio是一款在线转换文件的简 查看详情

gridview实现拖拽排序以及数据交互(代码片段)

...上,如果是两个GridView之间实现拖拽效果,并要实现数据交互。一、效果图:                 实现这个效 查看详情

一分钟内让你理解什么是产品经理?

前几天在某论坛上看见一个段子,生动形象地描绘出了产品经理、程序员、需求者三者之间那无以言表的关系图。看完这个段子也深刻体会到今年刚上线的大大神平台责任重大,该平台主要以产品经理为特色推出,平台又要怎样... 查看详情

一分钟让你了解芯片工作的心脏——晶振

晶振概念:在振荡器中采用一个特殊的元件——石英晶体,它可以产生频率高度稳定的交流信号,这种采用石英晶体的振荡器称为晶体振荡器,简称晶振。制作方法:从一块石英晶体上按一定方位角切下薄片(... 查看详情

一分钟带你了解正则

参考技术A在Python3中正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。Python自1.5版本起增加了re模块,它提供Perl风格的正则表达式模式。re模块使Python语言拥有全部的正则表达式功能。co... 查看详情

一分钟带你全面了解计算机考研常识,让你对考研不再陌生!

以下考研信息仅适配于计算机专业,其他专业仅供参考!一、考研全国硕士研究生统一招生考试(UnifiedNationalGraduateEntranceExamination,简称“考研”或“统考”)是指教育主管部门和招生机构为选拔研究生而组... 查看详情

使窗体拥有透明效果的api

...ndowAttributes是windows的新api,win2000以上才支持,它能使使窗体拥有透明效果.我在Google搜了下,介绍SetLayeredWindowAttributes的文章大多是delphi 查看详情

如何让你产品的用户拥有一流的上传体验

本文由 网易云发布。 在当下的互联网产品中,短视频、线上KTV、线上多媒体互动等场景可谓是越来越多。此类产品非常依赖价值创造者,比如美女主播,小视屏制作者,音乐制作人等等,为价值提供者创造一个优质的用... 查看详情

android面试题

Android程序员面试宝典自定义控件一分钟实现贴纸功能一分钟实现TextView高亮一分钟实现新手引导页一分钟实现ViewPager卡片一分钟实现加载对话框一分钟实现轮播图一分钟实现GridView拖拽一分钟实现底部导航栏一分钟实现底部Fragmen... 查看详情

一分钟拥有一家数字资产平台,金猫kinmall是怎么做到的?

...数字资产交易所,审核时间一般为3-4小时,最短可实现30分钟极速开所,大大节约了开所时间和成本。平台粉丝流量共享:众多开所方,可在金猫平台内实现流量、项目粉丝资源共享,同时金猫平台还会通过行之有效的营销手段... 查看详情