Android 9.0 app全屏通过系统属性控制手势上滑是否显示虚拟导航栏和状态栏
1.前言
在9.0的系统rom产品定制化os开发中,在系统设置app的全屏后,默认会隐藏导航栏和状态栏,页面全屏显示的时候,
然后底部上滑会显示虚拟状态栏和导航栏显示几秒钟后会自动消失,由于项目开发需要要求通过api
来控制全屏时上滑是否显示虚拟导航栏和状态栏,这就要从上滑事件分析看如何显示虚拟导航栏和状态栏的流程来控制是否显示
2.app全屏通过系统属性控制手势上滑是否显示虚拟导航栏和状态栏的核心类
-
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
-
frameworks/base/services/core/java/com/android/server/policy/BarController.java
3.app全屏通过系统属性控制手势上滑是否显示虚拟导航栏和状态栏的核心功能分析和实现
3.1PhoneWindowManager.java中关于系统手势的相关源码分析
// monitor for system gestures // TODO(multi-display): Needs to be display specific. mSystemGestures = new SystemGesturesPointerEventListener(context, new SystemGesturesPointerEventListener.Callbacks() { @Override public void onSwipeFromTop() { if (mStatusBar != null) { requestTransientBars(mStatusBar); } } @Override public void onSwipeFromBottom() { if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_BOTTOM) { requestTransientBars(mNavigationBar); } } @Override public void onSwipeFromRight() { if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_RIGHT) { requestTransientBars(mNavigationBar); } } @Override public void onSwipeFromLeft() { if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_LEFT) { requestTransientBars(mNavigationBar); } } @Override public void onFling(int duration) { if (mPowerManagerInternal != null) { mPowerManagerInternal.powerHint( PowerHint.INTERACTION, duration); } } @Override public void onDebug() { // no-op } @Override public void onDown() { mOrientationListener.onTouchStart(); } @Override public void onUpOrCancel() { mOrientationListener.onTouchEnd(); } @Override public void onMouseHoverAtTop() { mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS); Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS); msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS; mHandler.sendMessageDelayed(msg, 500); } @Override public void onMouseHoverAtBottom() { mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS); Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS); msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION; mHandler.sendMessageDelayed(msg, 500); } @Override public void onMouseLeaveFromEdge() { mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS); } }); mImmersiveModeConfirmation = new ImmersiveModeConfirmation(mContext); mWindowManagerFuncs.registerPointerEventListener(mSystemGestures);
在PhoneWindowManager.java的上述源码中,可以看出在SystemGesturesPointerEventListener中的相关源码中
在onSwipeFromBottom() 就是系统手势上滑处理的方法,然后掉requestTransientBars(mNavigationBar);执行相关功能
接下来分析下requestTransientBars(mNavigationBar)的相关源码
private void requestTransientBars(WindowState swipeTarget) { synchronized (mWindowManagerFuncs.getWindowManagerLock()) { if (!isUserSetupComplete()) { // Swipe-up for navigation bar is disabled during setup return; } boolean sb = mStatusBarController.checkShowTransientBarLw(); boolean nb = mNavigationBarController.checkShowTransientBarLw() && !isNavBarEmpty(mLastSystemUiFlags); if (sb || nb) { // Don't show status bar when swiping on already visible navigation bar if (!nb && swipeTarget == mNavigationBar) { if (DEBUG) Slog.d(TAG, "Not showing transient bar, wrong swipe target"); return; } // add core start int settings_custom = Settings.Global.getInt(getContext().getContentResolver(),"settings_custom",0); if (settings_custom ==1){ if (sb) mStatusBarController.showTransient(); if (nb) mNavigationBarController.showTransient(); } // add core end mImmersiveModeConfirmation.confirmCurrentPrompt(); updateSystemUiVisibilityLw(); } } }
在PhoneWindowManager.java的上述源码中,可以看出在requestTransientBars(WindowState swipeTarget)中的
上述方法,在通过代码中
if (sb) mStatusBarController.showTransient();
if (nb) mNavigationBarController.showTransient();
来判断是否显示状态栏和导航栏,所以通过上述增加系统属性根据系统属性值来判断是否打开系统状态栏和导航栏来实现功能的开发
3.2 StatusBarController.java关于状态栏的相关代码
public void setContentFrame(Rect frame) { mContentFrame.set(frame); } public void setShowTransparent(boolean transparent) { if (transparent != mShowTransparent) { mShowTransparent = transparent; mSetUnHideFlagWhenNextTransparent = transparent; mNoAnimationOnNextShow = true; } } public void showTransient() { if (mWin != null) { setTransientBarState(TRANSIENT_BAR_SHOW_REQUESTED); } } public boolean checkShowTransientBarLw() { if (mTransientBarState == TRANSIENT_BAR_SHOWING) { if (DEBUG) Slog.d(mTag, "Not showing transient bar, already shown"); return false; } else if (mTransientBarState == TRANSIENT_BAR_SHOW_REQUESTED) { if (DEBUG) Slog.d(mTag, "Not showing transient bar, already requested"); return false; } else if (mWin == null) { if (DEBUG) Slog.d(mTag, "Not showing transient bar, bar doesn't exist"); return false; } else if (mWin.isDisplayedLw()) { if (DEBUG) Slog.d(mTag, "Not showing transient bar, bar already visible"); return false; } else { return true; } }
从BarController.java的上述相关代码中可以发现StatusBarController继承
BarController实现相关方法,核心方法就是在BarController.java中实现的
然后通过调用showTransient()来实现状态栏的 显示,而通过checkShowTransientBarLw()
来返回当前的状态栏导航栏是否显示,然后决定是否需要显示导航栏状态栏
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库