获取状态栏高度
public static int getStatusBarHeight(Context context) { int result = 0; int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { result = context.getResources().getDimensionPixelSize(resourceId); } return result;}
或者
getWindow().getDecorView().setOnApplyWindowInsetsListener((v, insets) -> { int statuBarHeight = insets.getStableInsetTop(); return insets;});
获取导航栏高度
public static int getNavigationBarHeight(Context context) { int result = 0; int resourceId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android"); if (resourceId > 0) { result = context.getResources().getDimensionPixelSize(resourceId); } return result;}
或者
getWindow().getDecorView().setOnApplyWindowInsetsListener((v, insets) -> { int navigationBarHeight = insets.getStableInsetBottom(); return insets;});
其他数据
系统的各种数据定义位于SDK的xml文件中:
android-30/data/res/values/dimens.xml
<dimen name="toast_y_offset">24dpdimen><dimen name="status_bar_height">@dimen/status_bar_height_portraitdimen><dimen name="status_bar_height_portrait">24dpdimen><dimen name="status_bar_height_landscape">@dimen/status_bar_height_portraitdimen><dimen name="navigation_bar_height">48dpdimen><dimen name="navigation_bar_height_landscape">48dpdimen><dimen name="navigation_bar_width">48dpdimen>
通过key可以获取对应的值。
修改导航栏、状态栏背景色
getWindow().setStatusBarColor(Color.RED);getWindow().setNavigationBarColor(Color.RED);
源码
导航栏和状态栏源码相似
#PhoneWindow@Overridepublic void setStatusBarColor(int color) { mStatusBarColor = color; mForcedStatusBarColor = true; if (mDecor != null) { mDecor.updateColorViews(null, false ); }}
#DecorViewpublic static final ColorViewAttributes STATUS_BAR_COLOR_VIEW_ATTRIBUTES = new ColorViewAttributes(SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS, Gravity.TOP, Gravity.LEFT, Gravity.RIGHT, Window.STATUS_BAR_BACKGROUND_TRANSITION_NAME, com.android.internal.R.id.statusBarBackground, FLAG_FULLSCREEN, ITYPE_STATUS_BAR);public static final ColorViewAttributes NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES = new ColorViewAttributes( SYSTEM_UI_FLAG_HIDE_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION, Gravity.BOTTOM, Gravity.RIGHT, Gravity.LEFT, Window.NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME, com.android.internal.R.id.navigationBarBackground, 0 , ITYPE_NAVIGATION_BAR);private final ColorViewState mStatusColorViewState = new ColorViewState(STATUS_BAR_COLOR_VIEW_ATTRIBUTES);private final ColorViewState mNavigationColorViewState = new ColorViewState(NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES);
WindowInsets updateColorViews(WindowInsets insets, boolean animate) {... updateColorViewInt(mNavigationColorViewState, sysUiVisibility, calculateNavigationBarColor(), mWindow.mNavigationBarDividerColor, navBarSize, navBarToRightEdge || navBarToLeftEdge, navBarToLeftEdge, 0 , animate && !disallowAnimate, mForceWindowDrawsBarBackgrounds, controller);... updateColorViewInt(mStatusColorViewState, sysUiVisibility, calculateStatusBarColor(), 0, mLastTopInset, false , statusBarNeedsLeftInset, statusBarSideInset, animate && !disallowAnimate, mForceWindowDrawsBarBackgrounds, controller);}
调用updateColorViews
更新背景色的方法,还有如下位置:
#ViewRootImplprivate void performTraversals() {dispatchApplyInsets(host);}public void dispatchApplyInsets(View host) { mApplyInsetsRequested = false; WindowInsets insets = getWindowInsets(true ); host.dispatchApplyWindowInsets(insets);...}#Viewpublic WindowInsets dispatchApplyWindowInsets(WindowInsets insets) { ... return onApplyWindowInsets(insets);...}#DecorView@Overridepublic WindowInsets onApplyWindowInsets(WindowInsets insets) { ... insets = updateColorViews(insets, true); ... return insets;}
关于WindowInsets
WindowInsets
可以翻译为窗口附加物,一般是指一个界面中,不由开发者直接控制的部分,例如:状态栏、底部的导航栏等等。具体的类型在Type中有定义:
#WindowInsets.Typestatic final int FIRST = 1 << 0;static final int STATUS_BARS = FIRST;static final int NAVIGATION_BARS = 1 << 1;static final int CAPTION_BAR = 1 << 2;static final int IME = 1 << 3;static final int SYSTEM_GESTURES = 1 << 4;static final int MANDATORY_SYSTEM_GESTURES = 1 << 5;static final int TAPPABLE_ELEMENT = 1 << 6;static final int DISPLAY_CUTOUT = 1 << 7;static final int LAST = 1 << 8;static final int SIZE = 9;static final int WINDOW_DECOR = LAST;
可以向DecorView
添加监听,处理WindowInsets
getWindow().getDecorView().setOnApplyWindowInsetsListener((v, insets) -> { return insets;});
所以,可以在这里获取导航栏和状态栏的高度:
getWindow().getDecorView().setOnApplyWindowInsetsListener((v, insets) -> { int statuBarHeight = insets.getStableInsetTop(); int navigationBarHeight = insets.getStableInsetBottom(); return insets;});
也可以修改导航栏和状态栏的高度(好像没有应用场景):
getWindow().getDecorView().setOnApplyWindowInsetsListener((v, insets) -> { int statuBarHeight = 0; int navigationBarHeight = 0; return insets.replaceSystemWindowInsets(0,statuBarHeight,0,navigationBarHeight);;});
来源地址:https://blog.csdn.net/qq_23049111/article/details/126948312