- 首先需要知道状态栏能设置哪些内容。
(1)状态栏是否显示
(2)状态栏颜色设置
(3)状态栏图标和字体颜色修改- 其次,了解“沉浸模式”。
- 最后,如何通过Theme实现状态栏颜色修改。
1. 状态栏隐藏/显示
默认情况下,状态栏是显示的,那如何隐藏/显示呢?
- 方法1:设置Theme主题
在AndroidManifest.xml文件中修改theme为android:theme=”@android:style/Theme.NoTitleBar.Fullscreen” - 方法2:在setContentView方法前执行如下代码
requestWindowFeature(Window.FEATURE_NO_TITLE)
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
- 方法3:通过View的
setSystemUiVisibility
方法
View.SYSTEM_UI_FLAG_VISIBLE:
显示状态栏,Activity不全屏显示(恢复到有状态的正常情况)。
View.INVISIBLE:
隐藏状态栏,同时Activity会伸展全屏显示。
View.SYSTEM_UI_FLAG_FULLSCREEN:
Activity全屏显示,且状态栏被隐藏覆盖掉。
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN:
Activity全屏显示,但状态栏不会被隐藏覆盖,状态栏依然可见,Activity顶端布局部分会被状态遮住。
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION:
效果同View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
View.SYSTEM_UI_LAYOUT_FLAGS:
效果同View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION:
隐藏虚拟按键(导航栏)。有些手机会用虚拟按键来代替物理按键。
View.SYSTEM_UI_FLAG_LOW_PROFILE:
状态栏显示处于低能显示状态(low profile模式),状态栏上一些图标显示会被隐藏。
- 方法4:
getWindow().addFlags
getWindow().clearFlags
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN) //隐藏状态栏
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN) //显示状态栏
2. 状态栏颜色
默认是Dark样式,字体颜色为白色。
android4.4之前的版本,状态栏的背景色是不能修改的。在4.4版本,google增加了设置状态栏背景透明的方法。在5.x以上版本,google新增了设置状态栏背景色的方法。
2.1 android4.4 版本设置状态栏颜色
- 首先把状态栏设置为透明
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
设置为透明后,页面布局从状态栏开始,状态栏遮盖在页面布局上。
- 其次,修改状态栏颜色
本质上并不是修改状态栏颜色,而是修改了页面布局某组件的背景色,而透过透明状态栏看到的就是这个组件。实现的方式有两种:
方法1:适配系统窗口
android:fitsSystemWindows="true"
在页面布局的最外层设置。设置后的效果:状态栏的颜色显示最外层View的背景色
方法2:占位法
ViewGroup rootView = (ViewGroup) getWindow().getDecorView().findViewById(android.R.id.content);
rootView.setPadding(0, getStateBarHeight(), 0, 0);
// 根布局添加占位状态栏
ViewGroup decorView = (ViewGroup) getWindow().getDecorView();
View statusBarView = new View(this);
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
getStateBarHeight());
statusBarView.setBackgroundColor(color);
decorView.addView(statusBarView, lp);
2.2 android 5.+及以上系统设置状态栏颜色
android5.+新增状态栏颜色设置的方法
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(colorId);
android5.+以上系统,我自定义了两个方法:
-
setStatusColor(Activity activity,int color)
将状态栏背景色设置为任意颜色(除白色外) -
setStatusColorWhite(Activity activity)
android6.0+以上系统将状态栏背景色设置为白色,字体设置为黑色样式。而android5.+不能设置状态栏字体颜色,如果状态栏设置为白色,则状态栏字体颜色看不清(默认白色),因此设置为透明色。
调用哪个方法视具体情况而定,方法的实现见StatusBarUtils
工具类。
3. 状态栏字体和图标样式设置
在6.0以后Google增加了修改字体颜色的方法。
系统默认的状态栏字体样式是白色。可通过代码设置为黑字。
//设置为黑色
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
//设置为白色
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
4. 沉浸模式
沉浸模式必须在android4.4及其以上版本才能实现。
沉浸模式可理解为Activity全屏,但是状态栏覆盖显示在界面顶部。沉浸模式效果:
状态栏背景透明,覆盖在图片上
具体方法见:
StatusBarUtils.setImmersionModel(Activity activity)
5. 通过设置主题style实现
values文件夹中的styles文件:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="AppTheme.Main" parent="AppTheme"/>
values-v19文件夹中的styles文件:
<style name="AppTheme.Main" parent="AppTheme">
<item name="android:windowTranslucentStatus">true</item>
</style>
values-v21文件夹中的styles文件:
<style name="AppTheme.Main" parent="AppTheme">
<item name="android:windowTranslucentStatus">true</item>
<!--Android 5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色-->
<item name="android:windowTranslucentNavigation">true</item>
</style>
android:windowTranslucentNavigation
对应的是底部的虚拟键的背景。
6. StatusBarUtils工具类
public class StatusBarUtils {
/**
* 设置状态栏颜色
* 状态栏没有覆盖在页面布局上
* 设置为白色,使用{@link StatusBarUtils#setStatusColorWhite(Activity)} 方法
* @param activity activity
* @param color 状态栏颜色
*/
public static void setStatusColor(Activity activity,int color){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//5.0 以上直接设置状态栏颜色
Window window = activity.getWindow();
//After LOLLIPOP not translucent status bar
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//Then call setStatusBarColor.
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
activity.getWindow().setStatusBarColor(color);
//
} else if(Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT){
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
ViewGroup rootView = (ViewGroup) activity.getWindow().getDecorView().findViewById(android.R.id.content);
rootView.setPadding(0, getStateBarHeight(activity), 0, 0);
//根布局添加占位状态栏
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
View statusBarView = new View(activity);
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
getStateBarHeight(activity));
statusBarView.setBackgroundColor(color);
decorView.addView(statusBarView, lp);
}
}
public static int getStateBarHeight(Activity activity){
int result = 0;
int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = activity.getResources().getDimensionPixelSize(resourceId);
}
return result;
}
/**
* 状态栏颜色设置为白色
* 状态栏没有覆盖在页面布局上
* android6.0以上系统,状态栏字体设置为黑色
* android5.+系统,状态栏设置为透明
* android4.4 系统,状态栏设置为透明
* android 4.4以下系统,不能设置状态栏颜色
* @param activity
*/
public static void setStatusColorWhite(Activity activity){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//5.0 以上直接设置状态栏颜色
Window window = activity.getWindow();
//After LOLLIPOP not translucent status bar
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//Then call setStatusBarColor.
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
activity.getWindow().setStatusBarColor(Color.WHITE);
//设置状态栏字体颜色
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else if(Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP){
//5.+ 不能设置状态栏字体颜色,状态栏直接设置为白色,则状态栏字体颜色看不清,因此设置为透明色
setTranslucentStatus(activity);
}else if(Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT){
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
ViewGroup rootView = (ViewGroup) activity.getWindow().getDecorView().findViewById(android.R.id.content);
rootView.setPadding(0, getStateBarHeight(activity), 0, 0);
//根布局添加占位状态栏
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
View statusBarView = new View(activity);
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
getStateBarHeight(activity));
statusBarView.setBackgroundColor(Color.WHITE);
decorView.addView(statusBarView, lp);
}
}
/**
* 设置状态栏透明
* @param activity
*/
public static void setTranslucentStatus(Activity activity) {
//设置5.0及其以上系统状态栏透明
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = activity.getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
/**
* 设置沉浸模式,并且状态栏颜色为透明
* 其中状态栏为透明且覆盖在页面布局上
* android系统必须4.4及其以上
* @param activity activity
*/
public static void setImmersionModel(Activity activity) {
//设置5.0及其以上系统状态栏透明
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = activity.getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
}
第三方库:compile 'com.jaeger.statusbarutil:library:1.4.0'