【Android】沉浸模式:适配 StatusBar 和 NavigationBar

目录

 

setSystemUiVisibility方法

常用参数介绍:组合使用 | 位运算符

XML Style Theme布局设置状态栏与导航栏属性

设置状态栏颜色

设置状态栏字体颜色 安卓6.0后

获取状态栏和导航栏高度

fitsSystemWindows 与 clipToPadding 属性

游戏沉浸模式


setSystemUiVisibility方法


4.0之后,官方提供了这个方法,可以改变系统的UI可见性,使用方式如下:

扫描二维码关注公众号,回复: 8759407 查看本文章
View decor = getWindow().getDecorView()
decor.setSystemUiVisibility(flag);

常用参数介绍:组合使用 | 位运算符

// 隐藏状态栏,布局延伸到状态栏。下拉状态栏后布局回弹,并不会自动隐藏。
View.SYSTEM_UI_FLAG_FULLSCREEN
// 布局延伸到状态栏。
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
// 隐藏导航栏,布局延伸到导航栏。再次点击屏幕时截获一次焦点显示导航栏,布局回弹。
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
// 布局延伸到状态栏和导航栏。
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
// 沉浸式
View.SYSTEM_UI_FLAG_IMMERSIVE
// 次属性必须配合 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 一起使用
// 使用效果:隐藏导航栏。
// 沉浸式粘性
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
// 必须配合 View.SYSTEM_UI_FLAG_FULLSCREEN 和 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 使用
// 使用效果:隐藏状态栏和导航栏并延伸布局,下上拉Bar后显示Bar,一段时间后自动收回Bar
// 附加效果:状态栏和导航栏浅灰半透明
// API23引入,常用于改变状态栏字体颜色设置为黑色。
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
// 官方解释:请求状态栏以与灯光状态栏背景兼容的模式绘制。
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
// 官方解释:当使用其他布局标志时,我们希望fitSystemWindows(android.graphics.Rect)的内容插入有一个稳定的视图。
// 低调模式
View.SYSTEM_UI_FLAG_LOW_PROFILE
// 官方解释:View请求系统UI进入一个不引人注目的“低调”模式。
// 使用效果:状态栏内容亮度变暗,导航栏图标隐藏。(目前测试5.1版本有效,高版本或某些机型无效)
View.SYSTEM_UI_LAYOUT_FLAGS
// 官方解释:可能影响与系统用户界面相关的布局的标志。
// 个人测试效果:布局延伸到状态栏和导航栏
// 恢复(默认值)
View.SYSTEM_UI_FLAG_VISIBLE

XML Style Theme布局设置状态栏与导航栏属性

<!-- API21效果:状态栏与导航栏浅灰半透明并延伸布局 -->
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>

<!-- API21后状态栏和导航栏半透明浅灰色:设置完全透明 -->
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>

附加:无标题和ActionBar

<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">false</item>

设置状态栏颜色

// 通过Window对象更改
Window window = getWindow();

// 注意:如果设置了一下属性必须清除,否则无法设置颜色
// <item name="android:windowTranslucentStatus">true</item>
// <item name="android:windowTranslucentNavigation">true</item>
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

// 绘制一个背景栏
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

//设置颜色
window.setStatusBarColor(color);
window.setNavigationBarColor(color);

设置状态栏字体颜色 安卓6.0后

public void changeStatusBarTextColor(Window window, boolean isBlack) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            View decor = window.getDecorView();
            int flags = 0;
            if (isBlack) {
                flags = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
            }else {
                flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
            }
            decor.setSystemUiVisibility(flags);
        }
}

注意:theme使用sdk提供会设置无效,目前不知道系统设置了那个属性的问题。

设置无效解决

方式一:使用兼容包里的theme有效。

方式二:使用自定义Theme,不继承任何系统Theme。

获取状态栏和导航栏高度

	public static float getStatusBarHeight(Context context) {
		float statusBarHeight = 0;
		int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
		if (resourceId > 0) {
			statusBarHeight = context.getResources().getDimension(resourceId);
		}
		return statusBarHeight;
	}
	
	public static float getNavigationBarHeight(Context context) {
	    float result = 0;
	    int resourceId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
	    if (resourceId > 0) {
	        result = context.getResources().getDimension(resourceId);
	    }
	    return result;
	}

fitsSystemWindows 与 clipToPadding 属性

1. fitsSystemWindows

效果:防止布局延伸到状态栏和导航栏的。例如设置了如下属性

<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>

使用方式:

// 全局设置应用到全部 Activity
<style name="AppTheme" parent="AppBaseTheme">
        <item name="fitsSystemWindows">true</item>
</style>

// 应用到单个View或跟布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:orientation="vertical" >
    
    <LinearLayout 
	    android:layout_width="match_parent"
	    android:layout_height="80dp"
	    android:orientation="vertical"
        android:fitsSystemWindows="true"
	    android:background="@android:color/holo_blue_light" >
	    
    </LinearLayout>
    
</LinearLayout>

2. clipToPadding

效果:获取状态栏高度,并设置PaddingTop

使用方式:同 fitsSystemWindows 

游戏沉浸模式

// 使用:沉浸式粘性
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
配合 View.SYSTEM_UI_FLAG_FULLSCREEN 和 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 使用

使用沉浸式粘性,在按Home键后再次返回程序时会恢复状态,所以:

重写 Activity的onWindowFocusChanged(boolean hasFocus)方法

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if (hasFocus && Build.VERSION.SDK_INT >= 19) {
        View decorView = getWindow().getDecorView();
        decorView.setSystemUiVisibility(
        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
        | View.SYSTEM_UI_FLAG_FULLSCREEN
        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
    }
}

问题:点击EditText输入框后会恢复

解决:自行解决

适配  StatusBar 和 NavigationBar Demo APK 到Q群下载:361409208

参考郭林:https://blog.csdn.net/guolin_blog/article/details/51763825

发布了14 篇原创文章 · 获赞 16 · 访问量 1567

猜你喜欢

转载自blog.csdn.net/qq_42470947/article/details/104053976
今日推荐