从实践的角度给出一些沉浸式状态栏的方法,并解决沉浸式带来的问题
本文适用于4.4到更高的系统版本
实现的效果
状态栏透明
使用代码设置
123456789101112/*** 使状态栏透明 android 5.0以上* 获取根布局给其添加内容延伸到状态栏标记,并设置状态栏透明色*/public static void transparentStatusBar(Activity activity) {View decorView = activity.getWindow().getDecorView();int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;decorView.setSystemUiVisibility(option);activity.getWindow().setStatusBarColor(Color.TRANSPARENT);}修改
app
主题文件123456789<!-- app主题 --><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><!-- 状态栏透明 --><item name="android:windowTranslucentStatus">true</item></style>
状态栏字体颜色
实现图一效果,因为安卓碎片化的原因要分情况处理
android6.0
以上版本,支持深色模式,可以让状态的文字和图片变成黑色(默认状态栏文字和图片为白色)123if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);}android6.0
以下版本根据品牌系统适配小米
具体可以查看小米开放平台的开发文档
12345678910111213if (Build.MANUFACTURER.equals("Xiaomi")) {Class<? extends Window> clazz = activity.getWindow().getClass();try {int darkModeFlag = 0;Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");darkModeFlag = field.getInt(layoutParams);Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);extraFlagField.invoke(activity.getWindow(), darkModeFlag, darkModeFlag);} catch (Exception e) {e.printStackTrace();}}魅族
魅族系统貌似会自动根据界面的背景自己适配状态栏颜色
其他
可以去查看对应系统的开发文档
半透明状态栏
如果
UI
妹子不是特别要求透明状态栏的话,可以使用该方式(图2效果)其实就是给布局的顶部加一个状态栏大小高度一样的半透明控件
123456789101112131415161718192021222324252627282930313233343536373839404142434445//设置半透明状态栏protected void setHalfStatusBar() {//获取状态工具类int statusBarHeight = StatusBarUtil.getStatusBarHeight(this);if (statusBarHeight > 0) {//给根布局加一个和状态栏一样大小高度半透明黑色的状态栏,并放置在顶部ViewGroup content = (ViewGroup) findViewById(android.R.id.content);View translucentStatusBarView = StatusBarUtil.createTranslucentStatusBarView(this, 56);if (translucentStatusBarView != null) {content.addView(translucentStatusBarView);}}}/*** 获取状态栏高度** @param context context* @return 状态栏高度*/public static int getStatusBarHeight(Context context) {// 获得状态栏高度int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");int dimensionPixelSize = context.getResources().getDimensionPixelSize(resourceId);if (dimensionPixelSize <= 0) { // 如果为获取不到 就使用xml文件的dimensionPixelSize = context.getResources().getDimensionPixelSize(R.dimen.top_bar);}return dimensionPixelSize;}/*** 创建半透明矩形 View* 注意是LinearLayout.LayoutParams,因为默认添加到decorView** @param alpha 透明值* @return 半透明 View*/public static View createTranslucentStatusBarView(Activity activity, int alpha) {// 绘制一个和状态栏一样高的矩形View statusBarView = new View(activity);LinearLayout.LayoutParams params =new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));statusBarView.setLayoutParams(params);statusBarView.setBackgroundColor(Color.argb(alpha, 0, 0, 0));return statusBarView;}带来的问题
布局时会加上状态栏的高度
解决1:给布局或者第一个控件加上一个状态栏高度的
padding
或margin
解决2:
fitSystemWindows
调整系统窗口布局以适应你自定义的布局fitSystemWindows
带来的输入法问题 当给布局加上该属性后,布局会自动添加一个padding让布局的内容在状态栏之下,但是会导致输入弹出遮挡控件或者设置了
fitSystemWindows
属性的控件被拉伸。 大家可以参考网上的办法解决