目录
XML Style Theme 设置状态栏与导航栏是否延伸+透明和颜色
setSystemUiVisibility() 方法
4.0之后,官方提供了这个方法,可以改变系统的UI可见性,使用方式如下:
View decor = getWindow().getDecorView()
decor.setSystemUiVisibility(flag);
常用参数介绍:组合使用 | 位运算符
1. 隐藏状态栏,布局延伸到状态栏。下拉状态栏后布局回弹,并不会自动隐藏:
View.SYSTEM_UI_FLAG_FULLSCREEN
2. 布局延伸到状态栏:
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
3. 隐藏导航栏,布局延伸到导航栏。再次点击屏幕时截获一次焦点显示导航栏,布局回弹:
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
4. 布局延伸到状态栏和导航栏:
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
5. 沉浸式(使用效果:隐藏导航栏。):
View.SYSTEM_UI_FLAG_IMMERSIVE
// 此属性必须配合 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 一起使用
6. 沉浸式粘性:
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
// 必须配合 View.SYSTEM_UI_FLAG_FULLSCREEN 和 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 使用
// 使用效果:隐藏状态栏和导航栏并延伸布局,下上拉Bar后显示Bar,一段时间后自动收回Bar
// 附加效果:状态栏和导航栏浅灰半透明
7. API 23 引入,常用于改变状态栏字体颜色设置为黑色:
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
// 官方解释:请求状态栏以与灯光状态栏背景兼容的模式绘制。
8. 官方解释:当使用其他布局标志时,我们希望fitSystemWindows(android.graphics.Rect)的内容插入有一个稳定的视图。
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
9. 低调模式:
View.SYSTEM_UI_FLAG_LOW_PROFILE
// 官方解释:View请求系统UI进入一个不引人注目的“低调”模式。
// 使用效果:状态栏内容亮度变暗,导航栏图标隐藏。(目前测试5.1版本有效,高版本或某些机型无效)
10. 个人测试效果:布局延伸到状态栏和导航栏:
View.SYSTEM_UI_LAYOUT_FLAGS
// 官方解释:可能影响与系统用户界面相关的布局的标志。
11. 默认值:
View.SYSTEM_UI_FLAG_VISIBLE
XML Style Theme 设置状态栏与导航栏是否延伸+透明和颜色
隐藏状态栏并延伸,下拉状态栏后一段时间自动隐藏状态栏:
<!-- 隐藏状态栏并延伸,下拉状态栏后一段时间自动隐藏状态栏 -->
<item name="android:windowFullscreen">true</item>
状态栏与导航栏浅灰半透明并延伸布局:
<!-- 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提供会设置无效,目前不知道系统设置了那个属性的问题。
设置无效解决:
- 方式一:使用兼容扩展包(V4、V7)里的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 属性
例如设置了如下属性后:布局就会延伸到状态栏及导航栏。
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
效果:让之后添加的 Child View 防止延伸到状态栏和导航栏。使用方式:
// 全局设置应用到全部 Activity
<style name="AppTheme" parent="AppBaseTheme">
<item name="android: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>
游戏沉浸模式
沉浸式粘性:
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 输入框后会恢复,解决:自行解决
适配 Android 9.0 刘海屏
https://blog.csdn.net/guolin_blog/article/details/103112795
适配 StatusBar 和 NavigationBar Demo APK 我只上传到自己的Q群:361409208
参考:https://blog.csdn.net/guolin_blog/article/details/51763825