返回顶部
首页 > 资讯 > 前端开发 > node.js >Android SystemBar如何使用
  • 351
分享到

Android SystemBar如何使用

2024-04-02 19:04:59 351人浏览 薄情痞子
摘要

今天小编给大家分享一下Android SystemBar如何使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我

今天小编给大家分享一下Android SystemBar如何使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

ROM 去掉NavigationBar

resgrep NavigationBar相关的res,发现在framework/base/core/res/res/config.xml中可以通过config_showNavigationBar配置,继续jgrep showNavigationBar相关的java,发现在PhoneWindowManager中通过boolean变量mHasNavigationBar记录是否有NavigationBar,具体代码如下:

mHasNavigationBar = res.getBoolean(com.android.internal.R.bool.config_showNavigationBar);

需要注意的是mHasNavigationBar也可以通过系统提供的Property来标识,具体代码如下:

String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");

if ("1".equals(navBarOverride)) {

    mHasNavigationBar = false;

} else if ("0".equals(navBarOverride)) {

    mHasNavigationBar = true;

}

在PhoneWindowManager中存在一个类型为windowstate的变量mNavigationBar,WindowState是在PhoneWindowManger prepareAddWindow时会用到的一个interface,仔细看看prepareAddWindowLw方法

switch (attrs.type) {

    case TYPE_NAVIGATION_BAR:

       mContext.enforceCallinGorSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE, "PhoneWindowManager");

        if (mNavigationBar != null) {

            if (mNavigationBar.isAlive()) {

                return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;

            }

        }

        mNavigationBar = win;

        mNavigationBarController.setWindow(win);

        if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar);

       break;

}

判断type为TYPE_NAVIGATION_BAR的时候,给mNavigationBar赋值,并且mNavigationBarController setWindow,mNavigationBarController是一个用来操纵SystemBar Window的类,有兴趣可以详细看看这个类,位于/framework/base/services/core/java/com/android/server/policy。继续浏览代码会发现方法layoutNavigationBar,通过mNavigationBarController对mNavigationBar进行layout。

在framework/base/packages/SystemUI中PhoneStatusBar中makeStatusBarView有如下一段代码:

try {

    boolean showNav = mWindowManagerService.hasNavigationBar();

    if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);

    if (showNav) {

        createNavigationBarView(context);

    }

} catch (RemoteException ex) {

    // no window manager? good luck with that

}

根据WindowManagerService中的hasNavigationBar方法判断是否有NavigationBar,再看WindowMangerService中是调用了PhoneWindowManager中的hasNavigationBar方法,最终返回的就是最开始提到了mHasNavigationBar这个标识。在PhoneStatusBar有详细讲到如何createAndAddWindows,感兴趣可以再进一步了解。

SystemBar Translucent支持

Android在api 19的时候添加了两个WindowManager.LayoutParams,分别是FLAG_TRANSLUCENT_NAVIGATION、FLAG_TRANSLUCENT_STATUS。

在官方文档中有提到当为Window设置FLAG_TRANSLUCENT_NAVIGATION时,自动设置了System UI visibility SYSTEM_UI_FLAG_LAYOUT_STABLE、SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION,当为Window设置了FLAG_TRANSLUCENT_STATUS时,自动设置了System UI visibility SYSTEM_UI_FLAG_LAYOUT_STABLE、SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN。

显然,这时System UI visibility有发生变化,在PhoneWindowManager中有如下一段代码:

public int adjustSystemUiVisibilityLw(int visibility) {

        mStatusBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility);

        mNavigationBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility);

        mRecentsVisible = (visibility & View.RECENT_APPS_VISIBLE) > 0;

        mTvPictureInPictureVisible = (visibility & View.TV_PICTURE_IN_PICTURE_VISIBLE) > 0;

        // Reset any bits in mForceClearingStatusBarVisibility that

        // are now clear.

        mResettingSystemUiFlags &= visibility;

        // Clear any bits in the new visibility that are currently being

        // force cleared, before reporting it.

        return visibility & ——mResettingSystemUiFlags

            & ——mForceClearedSystemUiFlags;

}

可以看到前边提到的操控SystemBar的Controller这个时候发挥了作用,调用了其adjustSystemUiVisibilityLw,继续看BarController中相关代码

public void adjustSystemUiVisibilityLw(int oldVis, int vis) {

    if (mWin != null && mTransientBarState == TRANSIENT_BAR_SHOWING && (vis & mTransientFlag) == 0) {

        // sysui requests hide

        setTransientBarState(TRANSIENT_BAR_HIDING);

        setBarShowingLw(false);

    } else if (mWin != null && (oldVis & mUnhideFlag) != 0 && (vis & mUnhideFla == 0) {

        // sysui ready to unhide

        setBarShowingLw(true);

    }

}

同时,看到BarController中有applyTranslucentFlagLw,通过查找其调用处,发现依旧是在PhoneWindowManager中调用,以下是调用部分

// apply translucent bar vis flags

WindowState fullscreenTransWin = isStatusBarKeyguard() && !mHideLockScreen ? mStatusBar : mTopFullscreenOpaqueWindowState;

vis = mStatusBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVs);

vis = mNavigationBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis);

final int dockedVis = mStatusBarController.applyTranslucentFlagLw(mTopDockedOpaqueWindowState, 0, 0);

final boolean fullscreenDrawsStatusBarBackground =

        (drawsSystemBarBackground(mTopFullscreenOpaqueWindowState) && (vis & View.STATUS_BAR_TRANSLUCENT) == 0) || forcesDrawStatusBarBackground(mTopFullscreenOpaqueWindowState);

final boolean dockedDrawsStatusBarBackground = (drawsSystemBarBackground(mTopDockedOpaqueWindowState) && (dockedVis & View.STATUS_BAR_TRANSLUCENT) == 0) || forcesDrawStatusBarBackground(mTopDockedOpaqueWindowState);

可以看到在PhoneWindowManager中通过updateSystemBarsLw进行了相应的更新SystemBars。这个地方还有一个比较有意思的问题是,在实际使用这两个Flag的时候,会发现App自动延伸到StatusBar和NavigationBar下方,这是为何?

猜想,应该是App区域对系统下发的WindowInsets值做了处理,查看ActionBarOverlayLayout onApplyWindowInsets方法,可以发现通过computeFitSystemWindows对ActionBarOverlayLayout的measure时用到的insets值做了处理,查看View的computeFitSystemWindows方法

protected boolean computeFitSystemWindows(Rect inoutInsets, Rect outLocalInsets) {

    if ((mViewFlags & OPTIONAL_FITS_SYSTEM_WINDOWS) == 0 || mAttachInfo == null || ((mAttachInfo.mSystemUiVisibility & SYSTEM_UI_LAYOUT_FLAGS) == 0 && !mAttachInfo.mOverscanRequested)) {

        outLocalInsets.set(inoutInsets);

        inoutInsets.set(0, 0, 0, 0);

        return true;

    } else {

        // The application wants to take care of fitting system window for

        // the content...  however we still need to take care of any overscan here.

        final Rect overscan = mAttachInfo.mOverscanInsets;

        outLocalInsets.set(overscan);

        inoutInsets.left -= overscan.left;

        inoutInsets.top -= overscan.top;

        inoutInsets.right -= overscan.right;

        inoutInsets.bottom -= overscan.bottom;

        return false;

    }

}

可以发现这个地方,根据flag的判断通过overscan Rect对ActionBarOverlayLayout的insets值进行了修改(最近把这个处理移植到API 19以下了,嘿嘿嘿)。当然Google也没勇气对这个处理一锅端,因此App可以使用fitsSystemWindows属性来避免系统做这个处理,通过这个属性可以默认把insets值给到当前View的padding值,当然App也可以自己继承View的fitSystemWindows方法来自己处理insets。

SystemBar setColor支持

Android在API 21的时候为Window添加了setNavigationBarColor、setStatusBarColor,进一步提升SystemBar用户体验。

PhoneWindow继承Window具体实现了setNavigationBarColor、setStatusBarColor,具体代码如下:

public void setStatusBarColor(int color) {

    mStatusBarColor = color;

    mForcedStatusBarColor = true;

    if (mDecor != null) {

        mDecor.updateColorViews(null, false );

    }

}

public void setNavigationBarColor(int color) {

    mNavigationBarColor = color;

    mForcedNavigationBarColor = true;

    if (mDecor != null) {

        mDecor.updateColorViews(null, false );

        mDecor.updateNavigationGuardColor();

    }

}

不难发现主要是DecorView的updateColorViews在work,通过查看代码,可以明白是DecorView在SystemBar的位置add了对应的ColorStateView,这个有点类似PhoneWindowManager里边的WindowState,之后对ColotStateView里边的view进行操作即可,比如说setBackground来改变其颜色。

以上就是“Android SystemBar如何使用”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网node.js频道。

--结束END--

本文标题: Android SystemBar如何使用

本文链接: https://lsjlt.com/news/94155.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Android SystemBar如何使用
    今天小编给大家分享一下Android SystemBar如何使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我...
    99+
    2024-04-02
  • android thread如何使用
    在Android中,可以使用线程来执行耗时的任务,以避免阻塞主线程。以下是使用Android线程的一般步骤:1. 创建一个继承自Th...
    99+
    2023-09-29
    android
  • Android ActivityManager如何使用
    Android的ActivityManager类是一个系统级服务,用于管理应用程序的Activity,如启动Activity、关闭A...
    99+
    2023-08-18
    Android ActivityManager
  • Android FileProvider如何使用
    这篇文章主要介绍“Android FileProvider如何使用”,在日常操作中,相信很多人在Android FileProvider如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答...
    99+
    2023-07-05
  • Android中JNI如何使用
    Android中JNI如何使用,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1.导入C语言的类首先我们需要把C语言写的功能类放入我们的项目中。这里我直接从资料中...
    99+
    2023-06-20
  • Android中如何使用Html.fromHtml
    Android中如何使用Html.fromHtml,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1. 设置字体颜色的时候,颜色值需要用到转义符:如下代码所示:String&nb...
    99+
    2023-05-31
    android html.fromhtml
  • Android中selector如何使用
    今天就跟大家聊聊有关Android中selector如何使用,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Android  selector的详解前言:StateListD...
    99+
    2023-05-30
    android selector
  • Android中RecyclerView如何使用
    本篇文章给大家分享的是有关Android中RecyclerView如何使用,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。RecyclerView 是在Android suppo...
    99+
    2023-05-30
    android recyclerview
  • Android中AudioTrack如何使用
    Android中AudioTrack如何使用,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1、Android AudioTrack简介在android中播放声音...
    99+
    2023-05-30
    android
  • Android中SharedPreferences如何使用
    本篇文章为大家展示了Android中SharedPreferences如何使用,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Android  SharedPreferences详解获取Sh...
    99+
    2023-05-30
    android sharedpreferences
  • Android中OkHttpUtils如何使用
    Android中OkHttpUtils如何使用,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。引入:Android Studio使用前,对于Android Studio的用户,可...
    99+
    2023-05-30
    android okhttputils
  • Android中EfficientAdapte如何使用
    今天就跟大家聊聊有关Android中EfficientAdapte如何使用,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Android ListView之EfficientAdapt...
    99+
    2023-05-30
    android
  • Android 中 ActivityLifecycleCallbacks如何使用
    Android 中 ActivityLifecycleCallbacks如何使用,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。MyApplication如下:package...
    99+
    2023-05-30
    android activitylifecyclecallbacks
  • Android中setEmptyView如何使用
    Android中setEmptyView如何使用,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Android ListView之setEmptyView正确使用方法&nbs...
    99+
    2023-05-30
    android setemptyview
  • Android 中ContentProvider如何使用
    本篇文章为大家展示了Android 中ContentProvider如何使用,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Content Provider 的简单介绍: * Android中的Con...
    99+
    2023-05-30
    android contentprovider
  • Android的Span如何使用
    本篇内容介绍了“Android的Span如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Span集合段落类SpanBulletSpan...
    99+
    2023-07-02
  • Android中texttospeech如何使用
    在Android中使用TextToSpeech需要以下步骤:1. 在AndroidManifest.xml文件中添加以下权限:```...
    99+
    2023-08-26
    Android texttospeech
  • Fragment如何在Android中使用
    本篇文章给大家分享的是有关Fragment如何在Android中使用,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Fragment初探为了让界面可以在平板上更好地展示,Andr...
    99+
    2023-06-14
  • android radiobutton控件如何使用
    要使用Android RadioButton控件,您需要遵循以下步骤:1. 在XML布局文件中添加RadioButton控件。例如,...
    99+
    2023-09-21
    android
  • android navigation组件如何使用
    Android Navigation组件是一套可以帮助开发者轻松实现应用程序导航功能的框架。下面是使用Android Navigat...
    99+
    2023-10-09
    Android navigation
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作