Android 14 修改侧滑手势动画效果

涉及关键类

SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java

SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt

修改如下:

一,覆盖系统的默认手势效果

SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt

//start add code
private var slideBackView: SlideBackView? = null
//end add codeoverride fun setLayoutParams(layoutParams: WindowManager.LayoutParams) {this.layoutParams = layoutParams//start add codeslideBackView = SlideBackView(context, miShadeController)windowManager.addView(slideBackView, layoutParams)//end add code
}
override fun onMotionEvent(event: MotionEvent) {//start add codeif (slideBackView?.onTouchEventList(event) == true) return//end add code。。。。
}

二、实现手势动画效果

SlideBackView.java 手势动画效果

package com.android.systemui.navigationbar.gestural;import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.ActivityTaskManager;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;import java.util.Arrays;
import java.util.List;public class SlideBackView extends View {private static final int UN = -1;private static final int LEFT = 0;private static final int RIGHT = 1;private static final int MAX_WIDTH = 60;private static final int THRESHOLD = 50;private float startX = 0f;private float downX = 0f;private float moveX = 0f;private float moveY = 0f;private float upX = 0f;private float distanceX = 0f;private float speed = 0.5f;private int showType = UN;Path cubicPath;Paint wavePaint;private ValueAnimator valueAnimator;private Path arrowPath;private Paint arrowPaint;private static final int ARROW_SIZE = 8;private static final int SLIDE_HEIGHT = 400;private  MiShadeController controller;public SlideBackView(Context context, MiShadeController  controller) {this(context, null,controller);}public SlideBackView(Context context, AttributeSet attrs, MiShadeController  controller) {super(context, attrs);this.controller=controller;init();}private void init() {cubicPath = new Path();arrowPath = new Path();wavePaint = new Paint();wavePaint.setColor(0x11000000);wavePaint.setAntiAlias(true); // 启用抗锯齿arrowPaint = new Paint();arrowPaint.setColor(Color.WHITE);arrowPaint.setStyle(Paint.Style.STROKE);arrowPaint.setAntiAlias(true); // 启用抗锯齿arrowPaint.setStrokeWidth(2);valueAnimator = ObjectAnimator.ofFloat(1, 0);valueAnimator.setDuration(500);valueAnimator.addUpdateListener(animation -> {distanceX = distanceX * (Float) animation.getAnimatedValue();postInvalidate();});}private boolean isReachThreshold() {return startX < THRESHOLD || startX > getMeasuredWidth() - THRESHOLD;}private void initSlideDirection() {if (startX < THRESHOLD) {showType = LEFT;} else if (startX > getMeasuredWidth() - THRESHOLD) {showType = RIGHT;} else {showType = UN;}}private boolean isHideBackView = false;public  boolean onTouchEventList(MotionEvent event){if (valueAnimator.isRunning()) return false;int action = event.getAction();if (action == MotionEvent.ACTION_DOWN) {startX = downX = event.getX();if (!isReachThreshold()) {showType = UN;return false;}initSlideDirection();} else if (action == MotionEvent.ACTION_MOVE) {if (!isReachThreshold()) {showType = UN;return false;}moveX = event.getX();moveY = event.getY();distanceX = moveX - downX;postInvalidate();} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {if (!isReachThreshold()) {showType = UN;return false;}upX = event.getX();distanceX = upX - downX;handUpEvent();}return false;}private void handUpEvent() {if (valueAnimator.isRunning()) {valueAnimator.cancel();}valueAnimator.start();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if (showType == UN) return;// draw wavecubicPath.reset();int currentY = (int) Math.min(Math.max(SLIDE_HEIGHT/2f,moveY),getHeight()-SLIDE_HEIGHT/2f);// 凸起上部Yint topY = (int) (currentY - SLIDE_HEIGHT/2F);// 凸起下部Yint bottomY = (int) (currentY + SLIDE_HEIGHT/2F);// 凸起底部Xint footX = showType == LEFT ? 0 : getWidth();// 凸起顶部Xint peekX;if (showType == LEFT) {peekX = (int) (footX + Math.min(distanceX * speed, MAX_WIDTH));} else {peekX = (int) (footX - Math.min(Math.abs(distanceX) * speed, MAX_WIDTH));}int x1 = footX;int y1 = (int) (topY + SLIDE_HEIGHT*0.2F);int x2 = peekX;int y2 = (int) (topY + SLIDE_HEIGHT*0.3F);int x4 = peekX;int y4 = (int) (bottomY - SLIDE_HEIGHT*0.3F);int x5 = footX;int y5 = (int) (bottomY - SLIDE_HEIGHT*0.2F);cubicPath.moveTo(footX, topY);cubicPath.cubicTo(x1, y1, x2, y2, peekX, currentY);cubicPath.cubicTo(x4, y4, x5, y5, footX, bottomY);cubicPath.close();wavePaint.setAlpha((int) (Math.abs(distanceX) / MAX_WIDTH * 64));canvas.drawPath(cubicPath, wavePaint);arrowPath.reset();if (showType == LEFT) {float centerX = Math.min(distanceX * speed, MAX_WIDTH)/2F - 10;arrowPath.moveTo(centerX+ARROW_SIZE , currentY - ARROW_SIZE);arrowPath.lineTo(centerX, currentY);arrowPath.lineTo(centerX+ ARROW_SIZE , currentY + ARROW_SIZE);} else {float centerX = peekX+Math.min(Math.abs(distanceX) * speed, MAX_WIDTH)/2F + 6;arrowPath.moveTo(centerX + ARROW_SIZE, currentY - ARROW_SIZE);arrowPath.lineTo(centerX, currentY);arrowPath.lineTo(centerX + ARROW_SIZE, currentY + ARROW_SIZE);}canvas.drawPath(arrowPath, arrowPaint);}}

是不是很简单,但是很多兄弟看了很多文章 找了很多资料却始终找不到具体的修改位置,看我的一篇就够了 觉得我写的好的兄弟帮忙点个赞!!谢谢

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

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

相关文章

RHEL与CentOS:从同源到分流的开源操作系统演进

RHEL与CentOS&#xff1a;从同源到分流的开源操作系统演进 一、核心关系&#xff1a;源代码的重构与社区化 RHEL&#xff08;Red Hat Enterprise Linux&#xff09;与CentOS&#xff08;Community ENTerprise Operating System&#xff09;的关系可以概括为“同源异构”。RHE…

EFISH-SBC-RK3588 —— 厘米级定位 × 旗舰算力 × 工业级可靠‌

一、核心参数速览‌ ‌类别‌ ‌技术规格‌ ‌处理器‌ RK3588 八核&#xff08;4Cortex-A762.4GHz 4Cortex-A551.8GHz&#xff09; Mali-G610 GPU 6 TOPS NPU ‌定位能力‌ 双天线差分 GNSS&#xff08;GPS/北斗/GLONASS/Galileo&#xff09;&#xff0c;支持 RTK 动态…

【Unity 与c++通信】Unity与c++通信注意事项,参数传递

一、在Unity中使用c代码 Unity想调用C代码&#xff0c;则需要c开发人员打包成so库。 在Unity中通过DllImport&#xff0c;和dll一样调用。 需要注意的点&#xff1a; C代码需要extern"C"来封装成dll 因为unity默认使用c语言调用外部接口&#xff0c;会对c代码进行命…

DeepSeek+Mermaid:轻松实现可视化图表自动化生成(附实战演练)

目录 一、引言&#xff1a;AI 与图表的梦幻联动二、DeepSeek&#xff1a;大语言模型新星崛起2.1 DeepSeek 全面剖析2.2 多场景应用示例2.2.1 文本生成2.2.2 代码编写 三、Mermaid&#xff1a;代码式图表绘制专家3.1 Mermaid 基础探秘3.2 语法与图表类型详解3.2.1 流程图&#x…

霍格软件测试-JMeter高级性能测试一期

课程大小&#xff1a;32.2G 课程下载&#xff1a;https://download.csdn.net/download/m0_66047725/90631395 更多资源下载&#xff1a;关注我 当下BAT、TMD等互联网一线企业已几乎不再招募传统测试工程师&#xff0c;而只招测试开发工程师&#xff01;在软件测试技术栈迭代…

【Python数据库编程实战】从SQL到ORM的完整指南

目录 前言技术背景与价值当前技术痛点解决方案概述目标读者说明 一、技术原理剖析核心概念图解核心作用讲解关键技术模块说明技术选型对比 二、实战演示环境配置要求核心代码实现案例1&#xff1a;SQLite基础操作案例2&#xff1a;MySQL连接池案例3&#xff1a;SQLAlchemy ORM …

第1讲|R语言绘图体系总览(Base、ggplot2、ComplexHeatmap等)

目录 第1讲|R语言绘图体系总览 ✨ 引言:为什么R绘图如此重要? 🧩 1. Base绘图系统 🧩 2. ggplot2生态系统 🧩 3. ComplexHeatmap超级热图系统 🧩 4. 其他特色绘图库(快速了解) ✏️ 小结一句话 📅 预告下一讲 第1讲|R语言绘图体系总览 (Base、ggplot…

银行卡归属地查询的快速入门:API接口性能与安全兼备的高效实现

在金融和支付领域&#xff0c;获取银行卡的归属信息是一个常见的需求。**万维易源提供的“银行卡归属信息查询”API为开发者和企业提供了高效、便捷的银行卡信息查询服务&#xff0c;可以通过简单的接口调用获取银行卡的归属地、银行名称、电话号码、网址、卡种、银联Luhn效验和…

如何把两个视频合并成一个视频?无需视频编辑器即可搞定视频合并

在日常生活中&#xff0c;我们经常需要将多个视频片段合并成一个完整的视频&#xff0c;例如制作旅行记录、剪辑教学视频或拼接短视频素材。简鹿视频格式转换器是一款功能强大的工具&#xff0c;不仅可以进行视频格式转换&#xff0c;还支持视频合并功能。以下是使用简鹿视频格…

Android-KeyStore安全的存储系统

​ 在 Android 中&#xff0c;AndroidKeyStore 是一个安全的存储系统&#xff0c;用于存储加密密钥。它提供了一种安全的方式来生成、存储和管理密钥&#xff0c;而无需将密钥暴露给应用程序本身。以下是如何使用 AndroidKeyStore 的基本步骤和示例代码。 检查 AndroidKeyStor…

YOLOv12 改进有效系列目录 - 包含卷积、主干、检测头、注意力机制、Neck上百种创新机制 - 针对多尺度、小目标、遮挡、复杂环境、噪声等问题!

&#x1f525; 在 YOLO 系列一路狂飙之后&#xff0c;YOLOv12 带来了令人耳目一新的范式转变——它不再以 CNN 为绝对核心&#xff0c;而是首次 围绕注意力机制构建 YOLO 框架&#xff0c;在保证实时性的前提下&#xff0c;将检测精度再次推向新高度&#xff01; 为了进一步探…

网络准入控制系统:2025年网络安全的坚固防线

在当今数字化时代&#xff0c;网络安全已成为至关重要的议题。阳途网络准入控制系统作为保障网络安全的关键机制&#xff0c;发挥着不可替代的作用。 阳途网络准入控制系统核心目的在于确保只有合法、合规的设备与用户能够接入网络。从本质上讲&#xff0c;它通过一系列技术手段…

Graph Database Self-Managed Neo4j 知识图谱存储实践2:通过官方新手例子入门(未完成)

官方入门例子&#xff1a;neo4j-graph-examples/get-started: An introduction to graph databases and Neo4j for new users 官方例子仓库&#xff1a;https://github.com/neo4j-graph-examples 下载数据 git clone https://github.com/neo4j-graph-examples/get-started …

百度搜索AI开放计划:助力开发者通过MCP Server连接用户和应用

百度搜索AI开放计划&#xff1a;助力开发者通过MCP Server连接用户和应用 一、背景 2025年4月25日&#xff0c;百度在Create开发者大会上发布了全新的AI开放计划。这一计划的核心目的是实现用户和AI应用、MCP Server的高效链接&#xff0c;提供更流畅的互动体验&#xff0c;推…

方案精读:77页2024 集团企业IT技术架构规划方案【附全文阅读】

本文概述了集团企业2024年度IT技术架构规划方案的首课&#xff0c;旨在通过TOGAF企业架构框架方法论&#xff0c;系统规划并优化技术架构。项目核心目标在于结合集团信息化建设愿景与当前技术架构现状&#xff0c;制定前瞻性、标准化的技术架构规划及发展策略&#xff0c;以支撑…

C++ 日志系统实战第三步:熟悉掌握各种设计模式

全是通俗易懂的讲解&#xff0c;如果你本节之前的知识都掌握清楚&#xff0c;那就速速来看我的项目笔记吧~ 相关技术知识补充&#xff0c;也是最后的补充知识了~ 下文将加入项目代码编写&#xff01; 目录 设计模式 单例模式 饿汉模式 懒汉模式 工厂模式 简单…

开源作业调度框架Quartz框架详细使用说明

Quartz框架详细使用说明 Quartz 是一个功能强大的开源作业调度框架&#xff0c;广泛用于在Java应用程序中执行定时任务。以下是Quartz框架的详细使用说明、完整代码示例、同类框架对比以及总结表格。 1. Quartz框架概述 特点&#xff1a; 灵活的调度&#xff1a;支持多种调度方…

Java实现背景图片加自适应水印图片

由于每张图片的宽高比例不一致&#xff0c;希望使得水印在每张图上的尺寸可以跟随背景图变化&#xff0c;自动调整水印大小。避免每张背景的图所显示的logo水印不至于那么突兀。 一、导入所需Jar包 <dependency><groupId>cn.hutool</groupId><artifactId…

代理ip和实际ip的区别和联系

在互联网时代&#xff0c;IP地址是每个设备连接网络的“身份证”&#xff0c;但你是否知道IP地址还分为‌代理IP‌和‌实际IP‌&#xff1f;它们各自扮演什么角色&#xff1f;为什么有人选择使用代理IP&#xff1f;实际IP又有哪些不可替代的作用&#xff1f;本文将深入解析代理…

mybatis-plus里的com.baomidou.mybatisplus.core.override.MybatisMapperProxy 类的详细解析

以下是 com.baomidou.mybatisplus.core.override.MybatisMapperProxy 类的详细解析&#xff1a; 1. 类的作用 MybatisMapperProxy 是 MyBatis-Plus 框架中用于实现 Mapper 接口动态代理的核心类。它继承自 MyBatis 的 MapperProxy&#xff0c;并扩展了以下功能&#xff1a; …