安卓Activity上滑关闭效果实现

最近在做一个屏保功能,需要支持如图的上滑关闭功能。

因为屏保是可以左右滑动切换的,内部是一个viewpager

做这个效果的时候,关键就是要注意外层拦截触摸事件时,需要有条件的拦截,不能影响到内部viewpager的滑动处理。

以下是封装好的自定义view,继承自FrameLayout:

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;import androidx.annotation.NonNull;public class SlideCloseFrameLayout extends FrameLayout {/*** 滑动监听器*/public interface OnSlideCloseListener {/*** 滑动开始时调用*/void onStartSlide();/*** 滑动结束&动画结束时调用,isClose为true表示滑动关闭,为false表示滑动恢复原位* @param isClose*/void onStopSlide(boolean isClose);}private OnSlideCloseListener onSlideCloseListener;private static final String TAG = "SlideCloseFrameLayout";private float downY = 0; // 记录手指按下时的Y坐标private boolean isSlideAction = false; // 标记是否为滑动关闭动作private VelocityTracker velocityTracker = null; // 速度跟踪器private float lastTranslationY = 0; // 记录上一次的TranslationY值,用于滑动时的位置更新public SlideCloseFrameLayout(Context context) {super(context);}public SlideCloseFrameLayout(Context context, AttributeSet attrs) {super(context, attrs);}public SlideCloseFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}@Overridepublic boolean onInterceptTouchEvent(MotionEvent event) {try {int action = event.getAction();switch (action) {case MotionEvent.ACTION_DOWN:downY = event.getRawY();if (downY > getHeight() - getHeight() / 5f) {initVelocityTracker();velocityTracker.addMovement(event);return false; // 拦截事件}break;case MotionEvent.ACTION_MOVE:velocityTracker.addMovement(event);velocityTracker.computeCurrentVelocity(1000);float xVelocity = velocityTracker.getXVelocity();float yVelocity = velocityTracker.getYVelocity();if (Math.abs(yVelocity) > ViewConfiguration.get(getContext()).getScaledMinimumFlingVelocity()&& Math.abs(yVelocity) > Math.abs(xVelocity)) {// 如果超过最小判定距离,并且Y轴速度大于X轴速度,才视为纵向滑动if (yVelocity < 0) {// 向下滑动if (onSlideCloseListener != null) {onSlideCloseListener.onStartSlide();}isSlideAction = true;return true;}}break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL:isSlideAction = false;break;}} catch (Exception e) {e.printStackTrace();}return super.onInterceptTouchEvent(event);}@Overridepublic boolean onTouchEvent(MotionEvent event) {try {if (isSlideAction) {velocityTracker.addMovement(event);int action = event.getAction();switch (action) {case MotionEvent.ACTION_MOVE:float moveDistance = event.getRawY() - downY;if (moveDistance < 0) { // 仅当向上滑动时处理lastTranslationY = moveDistance;this.setTranslationY(moveDistance);}break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL:velocityTracker.computeCurrentVelocity(1000);float velocityY = velocityTracker.getYVelocity();if (Math.abs(velocityY) > 1000 || Math.abs(lastTranslationY) > getHeight() / 5f) {slideUpAndExit();} else {slideBack();}releaseVelocityTracker();isSlideAction = false;break;}return true;}} catch (Exception e) {e.printStackTrace();}return super.onTouchEvent(event);}public boolean isSlideAction() {return isSlideAction;}public OnSlideCloseListener getOnSlideCloseListener() {return onSlideCloseListener;}public void setOnSlideCloseListener(OnSlideCloseListener onSlideCloseListener) {this.onSlideCloseListener = onSlideCloseListener;}private void initVelocityTracker() {if (velocityTracker == null) {velocityTracker = VelocityTracker.obtain();} else {velocityTracker.clear();}}private void releaseVelocityTracker() {if (velocityTracker != null) {velocityTracker.recycle();velocityTracker = null;}}private void slideUpAndExit() {// 执行上移退出动画TranslateAnimation exitAnimation = new TranslateAnimation(0, 0, getTranslationY(), -getHeight());exitAnimation.setDuration(300);exitAnimation.setFillAfter(false);exitAnimation.setAnimationListener(new Animation.AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {// 动画结束后的操作setVisibility(View.GONE); // 隐藏或其他逻辑if (onSlideCloseListener != null) {onSlideCloseListener.onStopSlide(true);}}@Overridepublic void onAnimationRepeat(Animation animation) {}});startAnimation(exitAnimation);this.setTranslationY(0); // 重置TranslationY值}private void slideBack() {// 使用属性动画使视图回到原位ObjectAnimator animator = ObjectAnimator.ofFloat(this, "translationY", getTranslationY(), 0);animator.setDuration(300);animator.start();animator.addListener(new Animator.AnimatorListener(){@Overridepublic void onAnimationStart(@NonNull Animator animation) {}@Overridepublic void onAnimationEnd(@NonNull Animator animation) {if (onSlideCloseListener != null) {onSlideCloseListener.onStopSlide(false);}}@Overridepublic void onAnimationCancel(@NonNull Animator animation) {if (onSlideCloseListener != null) {onSlideCloseListener.onStopSlide(false);}}@Overridepublic void onAnimationRepeat(@NonNull Animator animation) {}});}
}

Activity使用时,只需要把根View设置为这个自定义view,然后透明主题,透明背景,同时关闭Activity的进入退出动画,便可以实现如图效果了。

嵌套使用时,不会影响到内部的Viewpager或其他可滑动view

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

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

相关文章

爬取豆瓣电影分类排行榜中的电影详情数据

进入界面&#xff0c;右键打开检测&#xff0c;选择网络 然后网页滚动条拉倒最下面使其刷出新的数据&#xff0c;然后查看数据包 编写代码 import requests import jsonif __name__ __main__:get_url https://movie.douban.com/j/chart/top_listheaders {User-Agent:Mozil…

边缘计算与云计算总结

一. EdgeGallery 简介 MEC场景下的EdgeGallery是让资源边缘化&#xff0c;实时完成移动网络边缘的业务处理&#xff0c;MEC场景下的EdgeGallery让开发者能更便捷地使用 5G 网络能力&#xff0c;让5G能力在边缘触手可及。 EdgeGallery是由华为、信通院、中国移动、中国联通、…

语音模块摄像头模块阿里云结合,实现垃圾的智能识别

语音模块&摄像头模块&阿里云结合 文章目录 语音模块&摄像头模块&阿里云结合1、实现的功能2、配置2.1 软件环境2.2 硬件配置 3、程序介绍3.1 程序概况3.2 语言模块SDK配置介绍3.3 程序文件3.3.1 开启摄像头的程序3.3.2 云端识别函数( Py > C ) & 串口程序…

Spring Boot 防护 XSS + SQL 注入攻击

XSS跨站脚本攻击 ① XSS漏洞介绍 跨站脚本攻击XSS是指攻击者往Web页面里插入恶意Script代码&#xff0c;当用户浏览该页之时&#xff0c;嵌入其中Web里面的Script代码会被解析执行&#xff0c;从而达到恶意攻击用户的目的。XSS攻击针对的是用户层面的攻击&#xff01; ② XSS…

【 MyBatis 】| 关于多表联查返回 List 集合只查到一条的 BUG

目录 一. &#x1f981; 写在前面二. &#x1f981; 探索过程2.1 开端 —— 开始写 bug2.2 发展 —— bug 完成2.3 高潮 —— bug探究2.4 结局 —— 效果展示 三. &#x1f981; 写在最后 一. &#x1f981; 写在前面 今天又是 BUG 气满满的一天&#xff0c;一个 xxxMapper.xm…

spark核心概念

DAG 所谓DAG就是有向无环图&#xff0c;其实就是个无环的流程&#xff0c;Spark的核心是根据RDD来实现的&#xff0c;Spark Scheduler!则为Spark核心实现的重要一环&#xff0c;其作用就是任务调度。Spark的任务调度就是如何组织任务去处理RDD中每个分区的数据&#xff0c;根据…

Day53:WEB攻防-XSS跨站SVGPDFFlashMXSSUXSS配合上传文件添加脚本

目录 MXSS UXSS&#xff1a;Universal Cross-Site Scripting HTML&SVG&PDF&SWF-XSS&上传&反编译(有几率碰到) SVG-XSS PDF-XSS Python生成XSS Flash-XSS 知识点&#xff1a; 1、XSS跨站-MXSS&UXSS 2、XSS跨站-SVG制作&配合上传 3、XSS跨站-…

Docker进阶:使用Docker部署Harbor私有镜像仓库

Docker进阶&#xff1a;使用Docker部署Harbor私有镜像仓库 1、安装Docker和Docker Compose1、安装Docker、Docker Compose2、验证Docker和Docker Compose是否成功安装3、先启动运行docker服务 2、下载并配置Harbor1、下载最新版本的Harbor离线安装包2、配置Harbor的主机名和管理…

京东云搭建幻兽帕鲁Palworld多人游戏联机服务器教程,1分钟开服

使用京东云服务器搭建幻兽帕鲁Palworld游戏联机服务器教程&#xff0c;非常简单&#xff0c;京东云推出幻兽帕鲁镜像系统&#xff0c;镜像直接选择幻兽帕鲁镜像即可一键自动部署&#xff0c;不需要手动操作&#xff0c;真正的新手0基础部署幻兽帕鲁&#xff0c;阿腾云atengyun.…

uni-app(使用阿里图标)

1.注册阿里矢量图标库 注册阿里图标库账号并登录&#xff0c;https://www.iconfont.cn/ 2.加入购物车 搜索适合自己的图标&#xff0c;加入购物车&#xff0c;如下图&#xff1a; 3.加入项目 我的->资源管理->我的项目->创建项目&#xff0c;然后返回购物车&#…

中国信通院 X StarRocks金融用户社区正式成立

在国家战略的推动下&#xff0c;开源技术正逐渐成为金融行业创新发展的重要驱动力。2024 年 3 月 26 日&#xff0c;中国信息通信研究院 X StarRocks 金融用户社区&#xff08;以下简称“社区”&#xff09;正式成立&#xff0c;这一举措旨在深化国内金融领域的开源生态建设&am…

粗略总结AI大模型学习需要了解的要点

目录 一、概念简介 二、兴起原因 三、相关要点 四、不足之处 五、总结 一、概念简介 AI大模型学习是指利用大规模数据集和强大计算能力进行深度学习模型的训练。随着数据的爆炸式增长和计算资源的提升&#xff0c;AI大模型学习成为了现代人工智能研究的重要方向。 二、兴起…

使用pytorch构建一个初级的无监督的GAN网络模型

在这个系列中将系统的构建GAN及其相关的一些变种模型&#xff0c;来了解GAN的基本原理。本片为此系列的第一篇&#xff0c;实现起来很简单&#xff0c;所以不要期待有很好的效果出来。 第一篇我们搭建一个无监督的可以生成数字 (0-9) 手写图像的 GAN&#xff0c;使用MINIST数据…

入门指南|营销中人工智能生成内容的主要类型 [新数据、示例和技巧]

由于人工智能技术的进步&#xff0c;内容生成不再是一项令人头疼的任务。随着人工智能越来越多地接管手动内容制作任务&#xff0c;营销人员明智的做法是了解现有的不同类型的人工智能生成内容&#xff0c;以及哪些内容从中受益最多。这些工具可以帮助我们制作对您的受众和品牌…

Synchronized锁、公平锁、悲观锁乐观锁、死锁等

悲观锁 认为自己在使用数据的时候一定会有别的线程来修改数据,所以在获取数据前会加锁,确保不会有别的线程来修改 如: Synchronized和Lock锁 适合写操作多的场景 乐观锁 适合读操作多的场景 总结: 线程8锁🔐 调用 声明 结果:先打印发送短信,后打印发送邮件 结论…

机器学习(三)

神经网络: 神经网络是由具有适应性的简单单元组成的广泛并行互连的网络&#xff0c;它的组织能够模拟生物神经系统对真实世界物体所作出的交互反应。 f为激活(响应)函数: 理想激活函数是阶跃函数&#xff0c;0表示抑制神经元而1表示激活神经元。 多层前馈网络结构: BP(误差逆…

OpenPLC_Editor 在Ubuntu 虚拟机安装记录

1. OpenPLC_Editor在虚拟机上费劲的装了一遍&#xff0c;有些东西已经忘了&#xff0c;主要还是python3 的缺失库版本对应问题&#xff0c;OpenPLC_Editor使用python3编译的&#xff0c;虚拟机的Ubuntu 18.4 有2.7和3.6两个版本&#xff0c;所以需要注意。 2. OpenPLC_Editor …

Svg Flow Editor 原生svg流程图编辑器(四)

系列文章 Svg Flow Editor 原生svg流程图编辑器&#xff08;一&#xff09; Svg Flow Editor 原生svg流程图编辑器&#xff08;二&#xff09; Svg Flow Editor 原生svg流程图编辑器&#xff08;三&#xff09; Svg Flow Editor 原生svg流程图编辑器&#xff08;四&#xf…

贪心算法--最大数

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 本题链接https://leetcode.cn/problems/largest-number/description/ class Solution { public:bool static compare(int a, int b){return (to_string(a) to_string(b)) > (to_string(b) to_string(a));}bool operato…

探索 2024 年 Web 开发最佳前端框架

前端框架通过简化和结构化的网站开发过程改变了 Web 开发人员设计和实现用户界面的方法。随着 Web 应用程序变得越来越复杂&#xff0c;交互和动画功能越来越多&#xff0c;这是开发前端框架的初衷之一。 在网络的早期&#xff0c;网页相当简单。它们主要以静态 HTML 为特色&a…