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.pswp.cn/diannao/80407.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/80407.shtml
英文地址,請注明出處:http://en.pswp.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; …