android微信朋友圈相册背景,Android 仿微信朋友圈图片拖拽返回

目前的app的动画效果是越来越炫了,很多主流app的图片预览返回都有类似功能,比较常见的是ios自带相册,微信朋友圈等等。自己项目中也有类似功能,最近整理了一下这个功能的代码,做个笔记记录,有兴趣的朋友可以点击源码。

网上已经有对应功能的三方库了,MyDragPhotoView 和 DragPhotoView等等。但是他们都是继承view去实现的。如果我想用到其他View/ViewGroup上,就不是很方便,需要重新自定义view,然后复制黏贴和修改。因此就有了这篇文章,这个效果可以加在任意View或者ViewGroup上。

效果图:

一般经常用到这个功能的,莫非就是图片预览和视频预览了。

视频控件效果

2d30934229e9

SVID_20190419_113022_123.gif

图片控件效果

2d30934229e9

SVID_20190515_151249_123.gif

使用步骤:

1.activity主题设为透明

true

2.初始化

DragCloseHelper dragCloseHelper = new DragCloseHelper(this);

3.如果是共享元素启动的页面,需要如下设置(强烈建议和共享元素一起使用,否则是没有灵魂的)

dragCloseHelper.setShareElementMode(true);

4.设置需要进行拖拽的View/ViewGroup,以及背景ViewGroup(必须要设置背景色)

dragCloseHelper.setDragCloseViews(parentV, childV);

5.设置监听

dragCloseHelper.setDragCloseListener(new DragCloseHelper.DragCloseListener() {

@Override

public boolean intercept() {

//默认false 不拦截。比如图片在放大状态,是不需要执行拖拽动画的等等。

return false;

}

@Override

public void dragStart() {

//拖拽开始。可以在此额外处理一些逻辑

}

@Override

public void dragging(float percent) {

//拖拽中。percent当前的进度,取值0-1,可以在此额外处理一些逻辑

}

@Override

public void dragCancel() {

//拖拽取消,会自动复原。可以在此额外处理一些逻辑

}

@Override

public void dragClose(boolean isShareElementMode) {

//拖拽关闭,如果是共享元素的页面,需要执行activity的onBackPressed方法,注意如果使用finish方法,则返回的时候没有共享元素的返回动画

if (isShareElementMode) {

onBackPressed();

}

}

});

6.处理touch事件

@Override

public boolean dispatchTouchEvent(MotionEvent event) {

if (dragCloseHelper.handleEvent(event)) {

return true;

} else {

return super.dispatchTouchEvent(event);

}

}

7.可以自定义最大拖拽距离和最小缩放尺寸

setMaxExitY(int maxExitY)

setMinScale(@FloatRange(from = 0.1f, to = 1.0f) float minScale)

原理:

很简单,就是touch事件传递,相信大家都已经滚瓜烂熟了。

大概步骤:

1.检测是否有拦截

2.ACTION_DOWN事件,初始化数据

3.ACTION_MOVE事件,如果多手指或者手指Id不一致,则复原,否则开始移动,同时更新拖拽View/ViewGroup的位置和大小。

4.ACTION_UP事件,判断是否超过指定的最大距离,如果超过,开始关闭动画,否则开始复原动画

核心代码如下:

/**

* 处理touch事件

*

* @param event

* @return

*/

public boolean handleEvent(MotionEvent event) {

if (dragCloseListener != null && dragCloseListener.intercept()) {

//拦截

isSwipingToClose = false;

return false;

} else {

//不拦截

if (event.getAction() == MotionEvent.ACTION_DOWN) {

//初始化数据

lastPointerId = event.getPointerId(0);

reset(event);

} else if (event.getAction() == MotionEvent.ACTION_MOVE) {

if (event.getPointerCount() > 1) {

//如果有多个手指

if (isSwipingToClose) {

//已经开始滑动关闭,恢复原状,否则需要派发事件

isSwipingToClose = false;

resetCallBackAnimation();

return true;

}

reset(event);

return false;

}

if (lastPointerId != event.getPointerId(0)) {

//手指不一致,恢复原状

if (isSwipingToClose) {

resetCallBackAnimation();

}

reset(event);

return true;

}

float currentY = event.getY();

float currentX = event.getX();

if (isSwipingToClose || Math.abs(currentY - mLastY) > 2 * viewConfiguration.getScaledTouchSlop()) {

//已经触发或者开始触发,更新view

mLastY = currentY;

mLastX = currentX;

float currentRawY = event.getRawY();

float currentRawX = event.getRawX();

if (!isSwipingToClose) {

//准备开始

isSwipingToClose = true;

if (dragCloseListener != null) {

dragCloseListener.dragStart();

}

}

//已经开始,更新view

mCurrentTranslationY = currentRawY - mLastRawY + mLastTranslationY;

mCurrentTranslationX = currentRawX - mLastRawX + mLastTranslationX;

float percent = 1 - Math.abs(mCurrentTranslationY / (maxExitY + childV.getHeight()));

if (percent > 1) {

percent = 1;

} else if (percent < 0) {

percent = 0;

}

parentV.getBackground().mutate().setAlpha((int) (percent * 255));

if (dragCloseListener != null) {

dragCloseListener.dragging(percent);

}

childV.setTranslationY(mCurrentTranslationY);

childV.setTranslationX(mCurrentTranslationX);

if (percent < minScale) {

percent = minScale;

}

childV.setScaleX(percent);

childV.setScaleY(percent);

return true;

}

} else if (event.getAction() == MotionEvent.ACTION_UP) {

//手指抬起事件

if (isSwipingToClose) {

if (mCurrentTranslationY > maxExitY) {

if (isShareElementMode) {

//会执行共享元素的离开动画

if (dragCloseListener != null) {

dragCloseListener.dragClose(true);

}

} else {

//会执行定制的离开动画

exitWithTranslation(mCurrentTranslationY);

}

} else {

resetCallBackAnimation();

}

isSwipingToClose = false;

return true;

}

} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {

//取消事件

if (isSwipingToClose) {

resetCallBackAnimation();

isSwipingToClose = false;

return true;

}

}

}

return false;

}

衍生文章

在发布文章之后,有人提出在滑动返回的过程中,上一个页面的背景是空白的。对此特意写了篇文章Android 共享元素动画分析及背景空白的解决方案

这两个问题和DragCloseHelper这个库没有直接关联。不过看完这两篇衍生文章,相信你对共享元素动画的过程有一个全新的认识。

本文参考资料

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/566852.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

erp采购总监个人总结_《用友 ERP 培训教程:财务核算/供应链管理/物料需求计划》ERP概述 : ERP基础知识...

第1章 ERP概述本章重点_- _ERP概要_- _ERP实施成功的必要条件_- _ERP几个重要的名词解释用友ERP-U8&#xff08;V8 .72&#xff09;简介及功能按钮说明1.1 ERP基础知识1.1.1 ERP基本概念ERP&#xff08;Enterprise Resources Planning&#xff09;中文叫做企业资源规划&…

soc 设计soc设计 uml实务手册_企业内训“软件需求设计建模方法学全程实例剖析”训练方案(2020年)...

※训练介绍※利润需求-设计。软件开发中&#xff0c;需求是解决“系统怎样好卖”的问题&#xff0c;设计是解决“降低开发成本”的问题。要迈向“低成本制造好卖的产品”的境界&#xff0c;并非喊喊口号就能达到。口号&#xff1a;我们只做最重要的需求&#xff0c;尽快把系统推…

鸿蒙分布式通讯子系统,【鸿蒙】分布式通信子系统--让华为手机发现Hi3861开发板...

目录&#xff1a;工具步骤运行结果工具&#xff1a;1. 华为手机&#xff0c;需要有多设备协同功能。在设置->更多连接->多设备协同&#xff0c;查看是否有多设备协同功能&#xff0c;此功能使用的就是coap协议。2. Hi3861开发板步骤&#xff1a;1. 修改源码&#xff0c;…

winform 统计大量数据重复的元素个数_DAY10——推断统计之概率与概率分布:常见的离散型概率分布...

「数学期望——某件事情大量发生之后的平均结果」----------------分割又分割----------------------昨天文章排版出了问题&#xff0c;今天重新排版。数据的三个统计维度&#xff1a;集中程度、离散程度、分布情况。集中程度&#xff1a;期望离散程度&#xff1a;方差、标准差…

xss跨站脚本攻击_常见攻击之xss跨站脚本攻击

前言随着互联网的不断发展&#xff0c;web应用的互动性也越来越强。相应的&#xff0c;在用户体验提升的同时安全风险也会跟着有所增加。今天&#xff0c;我们就来讲一讲web渗透中常见的攻击方式之一&#xff0c;XSS攻击。首先需要了解他是如何工作的&#xff0c;以及我们如何利…

缺陷调研报告_质量零缺陷 | 打造极致产品的质量管理之道

质量是政治质量是生命质量是效益为强化全员“零缺陷”质量意识&#xff0c;坚决打赢质量提升攻坚战&#xff0c;现开设“质量零缺陷”专栏&#xff0c;着力宣传全院各单位在加强质量管理&#xff0c;落实零缺陷理念等方面的典型做法和质量故事。今天为大家带来的是曾获得“全国…

oracle 从右往左截取_截取GIF、调分辨率、快捷拨号,三星这些功能让人爱不释手...

昨天三星5G手机正式上市后&#xff0c;今天又爆出苹果被三星拒绝后要转向华为购买5G芯片&#xff0c;苹果如此操作是真的走投无路了&#xff1f;再看看吃瓜群众们&#xff0c;吐槽一波接一波。​一会儿&#xff0c;嫌弃三星信号频段不完全&#xff0c;10nm的工艺制程太差。一会…

html中表单的校验的插件,功能强大的jquery.validate表单验证插件

本文实例为大家分享了jquery.validate表单验证的使用方法&#xff0c;供大家参考&#xff0c;具体内容如下1 、表单验证的准备工作在开启长篇大论之前&#xff0c;首先将表单验证的效果展示给大家。1.点击表单项&#xff0c;显示帮助提示2.鼠标离开表单项时&#xff0c;开始校验…

swing 显示文件下文件_Linux 文件权限详解

阅读五分钟&#xff0c;每日十点&#xff0c;和您一起终身学习&#xff0c;这里是程序员Android本篇文章主要介绍 Android 开发中的部分知识点&#xff0c;通过阅读本篇文章&#xff0c;您将收获以下内容:一、使用ls -l 显示文件的详细信息二、Linux下的文件权限分组三、drwx 代…

未来教育计算机二级书怎么样,未来教育计算机二级

1册图书1张光盘&#xff0c;轻松应对2018年一级计算机基础及MS Office应用考试 n 1.历年真题精选&#xff0c;全方位把握真考动向&#xff0c;具有练习价值 n (1)新大纲、新题型、新题库&#xff0c;全方位解读无纸化考试&#xff0c;帮助考生轻松过关。 n (2)精选2017年~2016年…

江苏计算机专业,行情火爆的计算机专业:江苏计算机专业高校最低录取分排序...

原标题&#xff1a;行情火爆的计算机专业&#xff1a;江苏计算机专业高校最低录取分排序现如今的十大热门专业里&#xff0c;计算机类专业总是稳居榜首&#xff01;几年前市场对计算机专业人才的需求非常大&#xff0c;计算机专业红得发紫&#xff0c;毕业生是"皇帝的女儿…

em算法 实例 正态分布_Petuum提出序列生成学习算法通用框架

近日&#xff0c;来自人工智能创业公司 Petuum 的研究人员发表论文&#xff0c;提出序列生成学习算法的通用框架——广义的熵正则化策略优化框架(Generalized Entropy-Regularized Policy Optimization)。该框架是对包括最大似然学习 (MLE)、增强学习 (RL) 等多种广泛使用的算法…

springboot 集成redis_一文详解Spring Boot 集成 Redis

redis设置&#xff1a;修改redis服务器的配置文件vim /usr/local/redis/bin/redis.confbind 0.0.0.0 protected-mode no重新启动redissystemctl restart redis.service #重新启动服务注意&#xff1a;服务器的话需要设置安全组开放端口1.导入依赖org.springframework.boot …

计算机用手机的网络,电脑做热点让手机上网_电脑开热点给手机用

2016-11-26 12:00:20你好!很高兴为你解答&#xff0c;有两个解决办法:1.在每台机的本地连接--属性--常规--internet协议(TCP/IP)--常规里,设置成"自动获取IP地址"2.在每台机的本地连接--...2017-01-06 14:44:121.打开任务栏右下角的网络连接&#xff0c;在弹出的界面…

shell开启飞行模式_原来手机飞行模式有这么多用处!99%的深圳人都不知道...

相信大家都知道我们的手机里有个功能叫「飞行模式」(又称航空模式)它可以关掉手机收发信号的装置避免手机信号对飞机飞行造成干扰来源&#xff1a;网络那么对于不常坐飞机的人来说「飞行模式」功能是不是毫无用处呢&#xff1f;当然不是今天易小姐就带大家解锁关于「飞行模式」…

联想微型计算机启天e4300,戴尔轻薄商务本Latitude E4200/E4300开卖

戴尔随迅驰2平台的发布全面更新了自己的Latitude商用笔记本产品线&#xff0c;之前15和14寸的E6000/E5000系列已经上市销售&#xff0c;今天两款轻薄型号E4300/E4200也摆上了戴尔美国官网的货架。13.3寸的E4300目标直指联想ThinkPad X300/X301系列&#xff0c;虽然在轻薄程度上…

医疗小程序源码_不懂商城小程序源码,如何快速创建小程序商城?

小程序在近来发展十分迅速&#xff0c;从微信小程序游戏出发&#xff0c;到现在渗透到各种功能类型&#xff0c;甚至已经扩展到了其他的应用程序上。那么如今很多的小程序商城应该怎么创建呢&#xff1f;不懂商城小程序源码也可以自己制作吗&#xff1f;当然可以&#xff0c;下…

计算机快捷键任务管理器,任务管理器快捷键,小编告诉你电脑如何打开任务管理器...

电脑系统的任务管理器是Windows提供有关计算机性能的信息&#xff0c;并显示了计算机上所运行的程序和进程的详细信息&#xff0c;从这里可以查看到当前系统的进程数、CPU使用比率、更改的内存、容量等数据。那么&#xff0c;任务管理器怎么样打开呢&#xff1f;下面&#xff0…

python webdriver 等待网页已登录_python基础编程:python+selenium实现163邮箱自动登陆的方法...

本文介绍了让我们先来预览一下代码运行效果吧&#xff1a;首先分析163邮箱登陆页面的网页结构(按F12或单击鼠标右键选择审查元素)1、定位到登陆框(注意登录框是一个iframe&#xff0c;如果不定位到iframe的话是无法找到之后的邮箱地址框和密码输入框的)2、定位到邮箱地址框(nam…

长沙计算机中级职称分数公布,大家所期待的2020年湖南省长沙中级职称评审公示...

原标题&#xff1a;大家所期待的2020年湖南省长沙中级职称评审公示年底了&#xff0c;各大考试差不多都快结束了。唯一就是湖南长沙的土建中级职称评审结果待公示&#xff0c;湖南岳阳&#xff0c;湘潭等地方也相继公示。2019年湖南省中级职称评审(长沙市)12月24号公示&#xf…