当前位置: 首页 > news >正文

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);}}

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

相关文章:

  • C语言面试高频题——strcat、strncat、strcmp、strcpy 哪些函数会导致内存溢出?
  • Android ActivityManagerService(AMS)深度解析
  • 基于javaweb的SpringBoot+MyBatis通讯录管理系统设计与实现(源码+文档+部署讲解)
  • 【维护窗口内最值+单调队列/优先队列】Leetcode 239. 滑动窗口最大值
  • Echarts 问题:自定义的 legend 点击后消失,格式化 legend 的隐藏文本样式
  • PowerShell脚本实现|从文件夹动画序列中均匀选取关键帧(保留首尾帧)
  • redis 数据类型新手练习系列——string类型
  • 【QQMusic项目复习笔记——音乐管理模块详解】第四章
  • Doris vs ClickHouse:深入对比MPP数据库聚合操作的核心区别
  • 重读《人件》Peopleware -(9-1)Ⅱ办公环境Ⅱ“你在这儿从早上9点到下午5点之间什么都做不成.“(上)
  • 2025 年导游证报考条件新政策解读与应对策略
  • 同样机身尺寸下伺服电机比无刷电机扭矩更大的原因
  • LangChain LCEL表达式语言简介
  • IP SSL证书常见问题助您快速实现HTTPS加密
  • ElementUi的tabs样式太难修改,自定义tabs标签页
  • Leetcode 2845 题解
  • Android WindowManagerService(WMS)框架深度解析
  • LibAI Lab闪耀AI出海峰会:技术深耕与全球化增长的双重奏
  • RabbitMQ 复习总结
  • Android 使用支付接口,需要进行的加密逻辑:MD5、HMAC-SHA256以及RSA
  • 特朗普将举行集会庆祝重返白宫执政百日,被指时机不当
  • 坤莹·帕塔玛·利斯达特拉任世界羽联主席
  • 第152次中老缅泰湄公河联合巡逻执法行动圆满结束
  • 饶权已任国家文物局局长
  • 四川一国企“80后”掌门人为报领导“知遇之恩”,盲目决策致数亿损失
  • ​王毅会见塔吉克斯坦外长穆赫里丁