Android13系统导航栏添加隐藏导航栏功能按钮

news2024/9/25 9:41:10

最近有个项目,客户要求在底部导航栏中添加一个可以隐藏整个导航栏的功能按钮,效果如下图:

具体方法如下:

1. 在frameworks/base做如下修改:

diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
old mode 100644
new mode 100755
index 5f59e781ef5e..538a0119cd09
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -33,4 +33,12 @@
         android:clipChildren="false"
         android:clipToPadding="false" />
 
+    <ImageView
+        android:layout_width="30dp"
+        android:layout_height="30dp"
+        android:id="@+id/navigation_hide_iv"
+        android:src="@drawable/ic_sysbar_hide"
+        android:layout_gravity="start|center_vertical"
+        android:layout_marginStart="@dimen/navigation_hide_button_start_margin" />
+        
 </com.android.systemui.navigationbar.NavigationBarView>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
old mode 100644
new mode 100755
index e09f7a6f0b57..6b19713923d6
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -60,4 +60,6 @@
 
     <dimen name="qs_panel_padding_top">@dimen/qqs_layout_margin_top</dimen>
     <dimen name="qs_panel_padding_top_combined_headers">@dimen/qs_panel_padding_top</dimen>
+	
+	<dimen name="navigation_hide_button_start_margin">40dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
old mode 100644
new mode 100755
index 6f1a13de60ed..40659c8542b9
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1567,4 +1567,6 @@
     <dimen name="dream_overlay_status_bar_ambient_text_shadow_dx">0.5dp</dimen>
     <dimen name="dream_overlay_status_bar_ambient_text_shadow_dy">0.5dp</dimen>
     <dimen name="dream_overlay_status_bar_ambient_text_shadow_radius">2dp</dimen>
+	
+	<dimen name="navigation_hide_button_start_margin">24dp</dimen>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
old mode 100644
new mode 100755
index 3789cbb1fb65..53d3fa4855aa
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
@@ -25,6 +25,7 @@ import static com.android.systemui.shared.recents.utilities.Utilities.isTablet;
 
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.hardware.display.DisplayManager;
@@ -47,6 +48,7 @@ import androidx.annotation.Nullable;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.statusbar.RegisterStatusBarResult;
 import com.android.settingslib.applications.InterestingConfigChanges;
+import com.android.systemui.R;
 import com.android.systemui.Dumpable;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
@@ -63,6 +65,7 @@ import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
 import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.phone.CentralSurfacesImpl;
 import com.android.wm.shell.back.BackAnimation;
 import com.android.wm.shell.pip.Pip;
 
@@ -294,6 +297,8 @@ public class NavigationBarController implements
         }
     }
 
+    private int displayId;
+
     /**
      * Adds a navigation bar on default display or an external display if the display supports
      * system decorations.
@@ -306,7 +311,7 @@ public class NavigationBarController implements
             return;
         }
 
-        final int displayId = display.getDisplayId();
+        displayId = display.getDisplayId();
         final boolean isOnDefaultDisplay = displayId == DEFAULT_DISPLAY;
 
         // We may show TaskBar on the default display for large screen device. Don't need to create
@@ -343,6 +348,7 @@ public class NavigationBarController implements
                             result.mImeWindowVis, result.mImeBackDisposition,
                             result.mShowImeSwitcher);
                 }
+                context.sendBroadcast(new Intent(CentralSurfacesImpl.ACTION_HIDE_NAVIGATIONBAR));
             }
 
             @Override
@@ -352,6 +358,13 @@ public class NavigationBarController implements
         });
     }
 
+    //edit by chain
+    public void initHideButton() {
+        NavigationBarView navigationBarView = getNavigationBarView(displayId);
+        View navigationHideIv = navigationBarView.findViewById(R.id.navigation_hide_iv);
+        navigationHideIv.setOnClickListener(v -> removeNavigationBar(displayId));
+    }
+
     void removeNavigationBar(int displayId) {
         NavigationBar navBar = mNavigationBars.get(displayId);
         if (navBar != null) {
@@ -368,6 +381,11 @@ public class NavigationBarController implements
         }
     }
 
+	public boolean canShowNavigationBar() {
+        NavigationBar navBar = mNavigationBars.get(displayId);
+        return navBar == null;
+    }
+
     /** @see NavigationBar#finishBarAnimations() */
     public void finishBarAnimations(int displayId) {
         NavigationBar navBar = mNavigationBars.get(displayId);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
old mode 100644
new mode 100755
index 0b63bbfec877..f78b86556d28
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -879,6 +879,8 @@ public class CentralSurfacesImpl extends CoreStartable implements
         wiredChargingRippleController.registerCallbacks();
     }
 
+	private RegisterStatusBarResult mBarRresult;
+
     @Override
     public void start() {
         mScreenLifecycle.addObserver(mScreenObserver);
@@ -917,14 +919,14 @@ public class CentralSurfacesImpl extends CoreStartable implements
         mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
         mWallpaperSupported = mWallpaperManager.isWallpaperSupported();
 
-        RegisterStatusBarResult result = null;
+        //RegisterStatusBarResult result = null;
         try {
-            result = mBarService.registerStatusBar(mCommandQueue);
+            mBarRresult = mBarService.registerStatusBar(mCommandQueue);
         } catch (RemoteException ex) {
             ex.rethrowFromSystemServer();
         }
 
-        createAndAddWindows(result);
+        createAndAddWindows(mBarRresult);
 
         if (mWallpaperSupported) {
             // Make sure we always have the most current wallpaper info.
@@ -939,30 +941,30 @@ public class CentralSurfacesImpl extends CoreStartable implements
         // Set up the initial notification state. This needs to happen before CommandQueue.disable()
         setUpPresenter();
 
-        if (containsType(result.mTransientBarTypes, ITYPE_STATUS_BAR)) {
+        if (containsType(mBarRresult.mTransientBarTypes, ITYPE_STATUS_BAR)) {
             showTransientUnchecked();
         }
-        mCommandQueueCallbacks.onSystemBarAttributesChanged(mDisplayId, result.mAppearance,
-                result.mAppearanceRegions, result.mNavbarColorManagedByIme, result.mBehavior,
-                result.mRequestedVisibilities, result.mPackageName, result.mLetterboxDetails);
+        mCommandQueueCallbacks.onSystemBarAttributesChanged(mDisplayId, mBarRresult.mAppearance,
+                mBarRresult.mAppearanceRegions, mBarRresult.mNavbarColorManagedByIme, mBarRresult.mBehavior,
+                mBarRresult.mRequestedVisibilities, mBarRresult.mPackageName, mBarRresult.mLetterboxDetails);
 
         // StatusBarManagerService has a back up of IME token and it's restored here.
-        mCommandQueueCallbacks.setImeWindowStatus(mDisplayId, result.mImeToken,
-                result.mImeWindowVis, result.mImeBackDisposition, result.mShowImeSwitcher);
+        mCommandQueueCallbacks.setImeWindowStatus(mDisplayId, mBarRresult.mImeToken,
+                mBarRresult.mImeWindowVis, mBarRresult.mImeBackDisposition, mBarRresult.mShowImeSwitcher);
 
         // Set up the initial icon state
-        int numIcons = result.mIcons.size();
+        int numIcons = mBarRresult.mIcons.size();
         for (int i = 0; i < numIcons; i++) {
-            mCommandQueue.setIcon(result.mIcons.keyAt(i), result.mIcons.valueAt(i));
+            mCommandQueue.setIcon(mBarRresult.mIcons.keyAt(i), mBarRresult.mIcons.valueAt(i));
         }
 
         if (DEBUG) {
             Log.d(TAG, String.format(
                     "init: icons=%d disabled=0x%08x lights=0x%08x imeButton=0x%08x",
                     numIcons,
-                    result.mDisabledFlags1,
-                    result.mAppearance,
-                    result.mImeWindowVis));
+                    mBarRresult.mDisabledFlags1,
+                    mBarRresult.mAppearance,
+                    mBarRresult.mImeWindowVis));
         }
 
         IntentFilter internalFilter = new IntentFilter();
@@ -1028,8 +1030,8 @@ public class CentralSurfacesImpl extends CoreStartable implements
         mAccessibilityFloatingMenuController.init();
 
         // set the initial view visibility
-        int disabledFlags1 = result.mDisabledFlags1;
-        int disabledFlags2 = result.mDisabledFlags2;
+        int disabledFlags1 = mBarRresult.mDisabledFlags1;
+        int disabledFlags2 = mBarRresult.mDisabledFlags2;
         mInitController.addPostInitTask(
                 () -> setUpDisableFlags(disabledFlags1, disabledFlags2));
 
@@ -1398,11 +1400,15 @@ public class CentralSurfacesImpl extends CoreStartable implements
         return mLifecycle;
     }
 
+	public static final String ACTION_HIDE_NAVIGATIONBAR = "action_hide_navigationbar";
+	public static final String ACTION_SHOW_NAVIGATIONBAR = "action_show_navigationbar";
     @VisibleForTesting
     protected void registerBroadcastReceiver() {
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
         filter.addAction(Intent.ACTION_SCREEN_OFF);
+        filter.addAction(ACTION_HIDE_NAVIGATIONBAR);
+        filter.addAction(ACTION_SHOW_NAVIGATIONBAR);
         mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, null, UserHandle.ALL);
     }
 
@@ -2660,6 +2666,13 @@ public class CentralSurfacesImpl extends CoreStartable implements
                 }
                 finishBarAnimations();
                 resetUserExpandedStates();
+            }else if (ACTION_HIDE_NAVIGATIONBAR.equals(action)){
+                mNavigationBarController.initHideButton();
+            }else if (ACTION_SHOW_NAVIGATIONBAR.equals(action)){
+                //Log.d("wzh", "mBroadcastReceiver.action="+action);
+                if (mNavigationBarController.canShowNavigationBar()){
+                    createNavigationBar(mBarRresult);
+                }
             }
             Trace.endSection();
         }
diff --git a/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java b/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
old mode 100644
new mode 100755
index 658f4efbdb2f..c095df9b0adb
--- a/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
+++ b/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
@@ -23,12 +23,14 @@ import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
 
 import android.annotation.NonNull;
 import android.content.Context;
+import android.content.Intent;
 import android.content.res.Resources;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.hardware.display.DisplayManagerGlobal;
 import android.os.Handler;
 import android.os.SystemClock;
+import android.util.Log;
 import android.util.Slog;
 import android.view.Display;
 import android.view.DisplayCutout;
@@ -194,12 +196,15 @@ class SystemGesturesPointerEventListener implements PointerEventListener {
                 if (mSwipeFireable) {
                     final int swipe = detectSwipe(event);
                     mSwipeFireable = swipe == SWIPE_NONE;
+                    //Log.d("wzh", "onPointerEvent().MotionEvent.ACTION_MOVE.swipe="+swipe);
                     if (swipe == SWIPE_FROM_TOP) {
                         if (DEBUG) Slog.d(TAG, "Firing onSwipeFromTop");
                         mCallbacks.onSwipeFromTop();
+                        mContext.sendBroadcast(new Intent("action_show_navigationbar"));
                     } else if (swipe == SWIPE_FROM_BOTTOM) {
                         if (DEBUG) Slog.d(TAG, "Firing onSwipeFromBottom");
                         mCallbacks.onSwipeFromBottom();
+                        mContext.sendBroadcast(new Intent("action_show_navigationbar"));
                     } else if (swipe == SWIPE_FROM_RIGHT) {
                         if (DEBUG) Slog.d(TAG, "Firing onSwipeFromRight");
                         mCallbacks.onSwipeFromRight();

2. 上面修改中有一行代码android:src="@drawable/ic_sysbar_hide"引用了一个ic_sysbar_hide.xml文件,该文件内容如下:其实就是那个隐藏按钮的矢量图代码

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="18dp"
    android:height="18dp"
    android:viewportWidth="35"
    android:viewportHeight="35">

    <path
        android:fillColor="#66cccccc"
        android:pathData="M21.314,25.837l9.898-9.9c0.782-0.782,2.049-0.782,2.829,0c0.78,0.781,0.781,2.049,0,2.831L22.73,30.079
            c-0.001,0.002-0.001,0.002-0.001,0.002c-0.39,0.391-0.902,0.586-1.415,0.586s-1.024-0.195-1.415-0.586L8.585,18.768
            c-0.782-0.781-0.779-2.049,0-2.831c0.781-0.782,2.049-0.782,2.831,0L21.314,25.837z"/>
</vector>

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

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

相关文章

后端学习:数据库MySQL学习

数据库简介 数据库&#xff1a;英文为 DataBase&#xff0c;简称DB&#xff0c;它是存储和管理数据的仓库。   接下来&#xff0c;我们来学习Mysql的数据模型&#xff0c;数据库是如何来存储和管理数据的。在介绍 Mysql的数据模型之前&#xff0c;需要先了解一个概念&#xf…

YOLO自制数据集及训练

使用 Make Sense 网站进行标注 https://www.makesense.ai/可以让AI帮你先标一下 一定要点一下 + ,不然不会加进去 导出标签

混淆矩阵、准确率、查准率、查全率、DSC、IoU、敏感度的计算

1.背景介绍 在训练的模型的时候&#xff0c;需要评价模型的好坏&#xff0c;就涉及到混淆矩阵、准确率、查准率、查全率、DSC、IoU、敏感度的计算。 2、混淆矩阵的概念 所谓的混淆矩阵如下表所示&#xff1a; TP:真正类&#xff0c;真的正例被预测为正例 FN:假负类&#xf…

OSI七层模型 | TCP/IP模型 | 网络和操作系统的联系 | 网络通信的宏观流程

文章目录 1.OSI七层模型2.TCP/IP五层(或四层)模型3.网络通信的宏观流程3.1.同网段通信3.2.跨网段通信 1.OSI七层模型 在计算机通信诞生之初&#xff0c;不同的厂商都生产自己的设备&#xff0c;都有自己的网络通讯标准&#xff0c;导致了不同厂家之间各种协议不兼容&#xff0…

Linux文本三剑客---grep

grep&#xff08;从文本或字符串种过滤特定内容。&#xff09; 格式&#xff1a;Usage: grep [OPTION]... PATTERNS [FILE]... 常用选项&#xff1a; -E 等价于 egrep 扩展正则 -i 忽略大小写 -w 匹配单词 -o 仅显示匹配内容 -r 递归匹配 -c 统计匹配的行数 -v 取反 -n 行号 -A…

ABAP 状态栏排除某些按钮

ABAP 状态栏排除某些按钮 GUI State状态栏 在状态栏这里有这些按钮&#xff0c;现在在导出界面要排除掉这些按钮&#xff1a; 将要排除的按钮追加到gt_code内表&#xff1a; gt_fcode功能码内表的定义 DATA:gt_fcode TYPE TABLE OF sy-ucomm,完整程序 *&---------…

SpringBoot不同的@Mapping使用

文章目录 一、介绍二、使用 一、介绍 一般Mapping类注解在Spring框架中用于将HTTP请求映射到对应的处理器方法。它们各自对应于不同类型的HTTP方法&#xff0c;主要用于RESTful Web服务中。以下是每个注解的作用&#xff1a; GetMapping: 用于映射HTTP GET请求到处理器方法。通…

Android读写文件,适配Q以上

Android Q升级了文件系统&#xff0c;访问文件不仅仅是说动态权限了&#xff0c;有各种限制。权限什么的就不赘述了&#xff0c;下面介绍一下在10以上的系统中访问文件。 首先是打开文件管理器 /*** 打开文件管理器 存储卡和外接U盘都可以访问*/public void openFileManager()…

【揭秘】ForkJoinTask全面解析

内容摘要 ForkJoinTask的显著优点在于其高效的并行处理能力&#xff0c;它能够将复杂任务拆分成多个子任务&#xff0c;并利用多核处理器同时执行&#xff0c;从而显著提升计算性能&#xff0c;此外&#xff0c;ForkJoinTask还提供了简洁的API和强大的任务管理机制&#xff0c…

Blender教程-编辑模式点线面的选择-06

一、新建立方体 ShiftA新建立方体用于演示 二、模式切换 按TAB键切换为编辑模式 点模式 在点模式下可以选择中物体的顶点。 线模式&#xff08;边模式&#xff09; 面模式 在熟悉编辑模式下的点线面基础操作以后&#xff0c;我们后续建模会以此为基础教程。

D. Epic Transformation(堆+贪心)

思路&#xff1a;我们删的策略是从次数多的数开始删&#xff0c;每次取两种不同的数&#xff0c;每种删去一个&#xff0c;然后放回堆中。 代码&#xff1a; void solve(){int n;cin >> n;map<int,int>mp;for(int i 1;i < n;i ){int x;cin >> x;mp[x] …

CAD-autolisp(二)——选择集、命令行设置对话框、符号表

目录 一、选择集1.1 选择集的创建1.2 选择集的编辑1.3 操作选择集 二、命令行设置对话框2.1 设置图层2.2 加载线型2.3 设置字体样式2.4 设置标注样式&#xff08;了解即可&#xff09; 三、符号表3.1 简介3.2 符号表查找3.2 符号表删改增 一、选择集 定义&#xff1a;批量选择…

ubuntu 20.04 更新 autoconf 版本

前言 由于最近打算交叉编译 python&#xff0c;依赖 libffi 库&#xff0c;而交叉编译 libffi 库&#xff0c;由于使用的是 github 上的 libffi&#xff0c;又提示 autoconf 版本太低了&#xff0c;所以&#xff0c;先更新 autoconf 的版本 当前 ubuntu 20.04 上安装的 autuco…

【数据分享】2015年泛第三极65国1km分辨率土壤侵蚀强度数据集(免费获取)

土壤数据是在环境、农业、生态等相关研究中都非常常用的数据&#xff01;我们之前发表过一篇介绍土壤数据来源的文章&#xff08;可查看之前推送的文章获悉详情&#xff09;&#xff01; 土壤侵蚀强度是土壤的重要属性&#xff01;本次我们给大家带来的是2015年泛第三极65国1k…

《合成孔径雷达成像算法与实现》Figure5.19

clc clear close all距离向参数 R_eta_c 20e3; % 景中心斜距 Tr 25e-6; % 发射脉冲时宽 Kr 0.25e12; % 距离向调频率 Fr 7.5e6; % 距离向采样率 Nrg 256; % 距离线采样点数 Bw abs(Kr*Tr); …

8.15合并区间(LC56)

算法&#xff1a; 和452. 用最少数量的箭引爆气球 (opens new window)和 435. 无重叠区间 (opens new window)都是一个套路。 这几道题都是判断区间重叠&#xff0c;区别就是判断区间重叠后的逻辑&#xff0c;本题是判断区间重贴后要进行区间合并。 步骤&#xff1a; 先排序…

自动化脚本不稳定,原来是软件弹窗惹的祸,2个方法解决!

很多同学在学习 App 自动化或者在项目中落地实践 App 自动化时&#xff0c;会发现编写的自动化脚本无缘无故的执行失败、不稳定。 而导致其问题很大原因是因为应用的各种弹窗&#xff08;升级弹窗、使用过程提示弹窗、评价弹窗等等&#xff09;&#xff0c;比如这样的&#xff…

nodejs下载 安装 配置环境

目录 1.下载 2、配置环境 1.下载 下载地址&#xff1a;https://nodejs.org/en/download/ 下载完成后&#xff0c;双击安装包&#xff0c;开始安装&#xff0c;一直点next即可。我把安装路径设置为 D:\Program Files\nodejs\ 安装完之后打开终端 windowR cmd 回车&#xff1…

C++:组合、继承与多态

面向对象设计的重要目的之一就是代码重用&#xff0c;这也是C的重要特性之一。代码重用鼓励人们使用已有的&#xff0c;得到认可并经过测试的高质量代码。多态允许以常规方式书写代码来访问多种现有的且已专门化了的相关类。继承和多态是面向对象程序设计方法的两个最主要的特性…

fix bug: FileNotFoundError: [Errno 2] No such file or directory: ‘nvcc‘

1.问题描述 运行的代码设计pycuda,会调用nvcc&#xff0c;确定已经安装cuda toolkit&#xff0c;在terminal中云运行 nvcc -V 能得到想到的结果&#xff1a; 但是在 pycharm中运行代码时提示&#xff1a; FileNotFoundError: [Errno 2] No such file or directory: nvcc 2.…