获取状态栏高度

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

24dp

@dimen/status_bar_height_portrait

24dp

@dimen/status_bar_height_portrait

48dp

48dp

48dp

通过key可以获取对应的值。

修改导航栏、状态栏背景色

getWindow().setStatusBarColor(Color.RED);

getWindow().setNavigationBarColor(Color.RED);

源码

导航栏和状态栏源码相似

#PhoneWindow

@Override

public void setStatusBarColor(int color) {

mStatusBarColor = color;

mForcedStatusBarColor = true;

if (mDecor != null) {

mDecor.updateColorViews(null, false /* animate */);

}

}

#DecorView

public 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 /* sideInset */, animate && !disallowAnimate,

mForceWindowDrawsBarBackgrounds, controller);

...

updateColorViewInt(mStatusColorViewState, sysUiVisibility,

calculateStatusBarColor(), 0, mLastTopInset,

false /* matchVertical */, statusBarNeedsLeftInset, statusBarSideInset,

animate && !disallowAnimate,

mForceWindowDrawsBarBackgrounds, controller);

}

调用updateColorViews更新背景色的方法,还有如下位置:

#ViewRootImpl

private void performTraversals() {

dispatchApplyInsets(host);

}

public void dispatchApplyInsets(View host) {

mApplyInsetsRequested = false;

WindowInsets insets = getWindowInsets(true /* forceConstruct */);

host.dispatchApplyWindowInsets(insets);

...

}

#View

public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {

...

return onApplyWindowInsets(insets);

...

}

#DecorView

@Override

public WindowInsets onApplyWindowInsets(WindowInsets insets) {

...

insets = updateColorViews(insets, true);

...

return insets;

}

关于WindowInsets

WindowInsets可以翻译为窗口附加物,一般是指一个界面中,不由开发者直接控制的部分,例如:状态栏、底部的导航栏等等。具体的类型在Type中有定义:

#WindowInsets.Type

static 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);

;

});