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

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.xdnf.cn/news/2009.html

相关文章:

  • xfce桌面汉化设置
  • 【防火墙 pfsense】2配置
  • 豆瓣图书数据采集与可视化分析(三)- 豆瓣图书数据统计分析
  • OSPF网络协议
  • Antd Modal Drawer 更改默认项
  • WSL 安装过程整理
  • 应用在物联网设备的爱普生可编程晶振SG-8018CA
  • Redis是单线程的,如何提高多核CPU的利用率?
  • 大学IP广播系统解决方案:构建数字化智慧化大学校园IP广播平台
  • 【含文档+PPT+源码】基于微信小程序的校园快递平台
  • HTML 模板技术与服务端渲染
  • 京东平台关键字搜索接口开发指南:Python实现与代码详解
  • PicoVR眼镜在XR融合现实显示模式下无法显示粒子问题
  • 大模型扫盲之推理性能指标全面详解
  • linux系统问题杂谈
  • Framework模块编译脚本利器
  • KafkaSpark-Streaming
  • C语言数据类型全面解析:从入门到精通
  • Django【应用 01】django-plotly-dash安装及使用
  • Java 设计模式心法之第22篇 - 备忘录 (Memento) - 捕获与恢复对象状态的“时光机”
  • 力扣-160.相交链表
  • 制作一款打飞机游戏23:编辑器ui
  • kafka与flume的整合、spark-streaming
  • Virtio 技术解析 | 框架、设备实现与实践指南
  • 【分布式系统中的“瑞士军刀”_ Zookeeper】一、Zookeeper 快速入门和核心概念
  • EasyRTC音视频实时通话嵌入式SDK,打造社交娱乐低延迟实时互动的新体验
  • Golang日志模块之xlog
  • 58、微服务保姆教程(一)
  • classfinal 修改过源码,支持jdk17 + spring boot 3.2.8
  • BGE-m3 和 BCE-Embedding 模型对比分析