700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Android沉浸式状态栏(透明系统状态栏)

Android沉浸式状态栏(透明系统状态栏)

时间:2020-07-24 20:39:57

相关推荐

Android沉浸式状态栏(透明系统状态栏)

Android沉浸式状态栏(透明系统状态栏)的目的:顶部系统状态栏和App的导航栏一体化,不给用户突兀的感觉,使用户把更多的视角留在我们的App上。

沉浸式状态栏的兼容情况

fitsSystemWindows

fitsSystemWindows,这个属性在沉浸式状态中扮演着非常重要的角色:

该属性只作用在sdk>=19的系统上就是高于4.4的系统,android:fitsSystemWindows默认值为false。基于系统窗口(如status bar)调整视图布局。只有在设置了透明状态栏(StatusBar)或者导航栏(NavigationBar)此属性才会生效,为true,将调整视图padding为系统窗口预留出空间。

当设置了透明状态栏(StatusBar)时:布局会扩展到StatusBar的位置,同时所有设置了android:fitsSystemWindows="true"属性的view会自动添加一个值等于状态栏高度的paddingTop

<item name="android:windowTranslucentStatus">true</item>或者if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);}

当设置了透明导航栏(NavigationBar)时:布局会扩展到NavigationBar的位置,同时所有设置了android:fitsSystemWindows="true"属性的view会自动添加一个值等于导航栏高度的paddingBottom。

<item name="android:windowTranslucentNavigation">true</item>或者if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);}

沉浸式状态栏实现的一般思路

4.4以下版本:我们可以对StatusBar和 NavigationBar进行显示和隐藏操作,但无法实现沉浸式状态栏。

Android4.4(API 19) - Android 5.0(API 21):通过FLAG_TRANSLUCENT_STATUS设置状态栏为透明并且为全屏模式,然后通过添加一个与StatusBar 一样大小的View,将View 的 background 设置为我们想要的颜色,从而来实现沉浸式。

Android 5.0(API 21)以上版本:在Android 5.0的时候,加入了一个重要的属性和方法 android:statusBarColor (对应方法为 setStatusBarColor),通过这个方法我们就可以轻松实现沉浸式。也就是说,从Android5.0开始,系统才真正的支持沉浸式。

Android 6.0(API 23)以上版本:Android6.0以上的实现方式和Android 5.0 +是一样,但从Android 6.0(API 23)开始,我们可以改状态栏的绘制模式,可以显示白色或浅黑色的内容和图标(除了魅族手机,魅族自家有做源码更改,6.0以下就能实现)

Android4.4(API 19) - Android 5.0(API 21)实现沉浸式的方式

可以在代码中设置,如下:

activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

也可以在theme 中设置属性windowTranslucentStatus,如下:

android:windowTranslucentStatus

效果如下:

效果如上图,可以看出,沉浸式的效果是出来了,但是也有一个问题,我们的标题栏和状态栏重叠了,相当于整个布局上移了StatusBar 的高度。为了让标题栏回到原来的位置,我们在标题栏的上方添加一个大小和StatusBar大小一样的View,View 的BackgroundColor 为标题栏一样的颜色,这个View起到一个占位的作用。这个时候,标题栏就会下移StatusBar的高度,回到正常的位置。

/*** 设置状态栏颜色** @param activity 需要设置的activity* @param color状态栏颜色值* @param statusBarAlpha 状态栏透明度*/public static void setColor(Activity activity, @ColorInt int color, int statusBarAlpha) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);activity.getWindow().setStatusBarColor(calculateStatusColor(color, statusBarAlpha));} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();int count = decorView.getChildCount();if (count > 0 && decorView.getChildAt(count - 1) instanceof StatusBarView) {decorView.getChildAt(count - 1).setBackgroundColor(calculateStatusColor(color, statusBarAlpha));} else {StatusBarView statusView = createStatusBarView(activity, color, statusBarAlpha);decorView.addView(statusView);}setRootView(activity);}}/*** 设置根布局参数*/private static void setRootView(Activity activity) {ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);rootView.setFitsSystemWindows(true);rootView.setClipToPadding(true);}/*** 计算状态栏颜色** @param color color值* @param alpha alpha值* @return 最终的状态栏颜色*/private static int calculateStatusColor(@ColorInt int color, int alpha) {float a = 1 - alpha / 255f;int red = color >> 16 & 0xff;int green = color >> 8 & 0xff;int blue = color & 0xff;red = (int) (red * a + 0.5);green = (int) (green * a + 0.5);blue = (int) (blue * a + 0.5);return 0xff << 24 | red << 16 | green << 8 | blue;}/*** 生成一个和状态栏大小相同的半透明矩形条** @param activity 需要设置的activity* @param color 状态栏颜色值* @param alpha 透明值* @return 状态栏矩形条*/private static StatusBarView createStatusBarView(Activity activity, @ColorInt int color, int alpha) {// 绘制一个和状态栏一样高的矩形StatusBarView statusBarView = new StatusBarView(activity);LinearLayout.LayoutParams params =new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));statusBarView.setLayoutParams(params);statusBarView.setBackgroundColor(calculateStatusColor(color, alpha));return statusBarView;}

其中StatusBarView 就是一个普通的View。

添加上述代码后,效果如下:

通过以上就可以实现Android 4.4 上的沉浸式状态栏

另外,如果是一张图片延伸到状态栏的话,直接设置FLAG_TRANSLUCENT_STATUS就可以了,如下:

小结:Android4.4上实现沉浸式状态栏的套路是:为window添加FLAG_TRANSLUCENT_STATUS Flag,然后添加一个和status bar 一样大小的View 站位,从而让让标题栏不会与status bar重叠。而图片延伸到状态栏只需要设置FLAG_TRANSLUCENT_STATUS就OK。

沉浸式在Android4.4 - Android5.0 之间的版本表现得不是很好,从上面贴的几张图就可以看出,状态栏的顶部有一个渐变,会显示出黑色的阴影(底部的导航栏也是一样的效果),在Android 5.0 版本已经被修复。

Android 5.0(API 21)以上实现沉浸式的方式

Android 5.0 是一个里程碑式的版本,从Android 5.0开始,Google 推出了全新的设计规范 Material Design,并且原生控件就可以实现一些炫酷的UI动效。从这个版本开始,google 加入了一个比较重要的方法setStatusBarColor (对应属性:android:statusBarColor),通过这个方法,可以很轻松地实现沉浸式状态栏。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);activity.getWindow().setStatusBarColor(calculateStatusColor(color, statusBarAlpha));}

想要这个方法生效,必须还要配合一个Flag一起使用,必须设置FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS ,并且不能设置FLAG_TRANSLUCENT_STATUS(Android 4.4才用这个)

效果如下:

当然也可以直接在Theme中使用,在values-v21文件夹下添加如下主题:

<style name="MDTheme" parent="Theme.Design.Light.NoActionBar"><item name="android:windowTranslucentStatus">false</item><item name="android:windowDrawsSystemBarBackgrounds">true</item><item name="android:statusBarColor">@android:color/holo_red_light</item></style>

效果和上面代码中添加的效果一样。

图片延伸到状态栏

Android 5.0使图片延伸到状态栏,只需设置windowTranslucentStatus,将 statusBarColor 设置为透明即可:

<style name="ImageTranslucentTheme" parent="Theme.AppCompat.DayNight.NoActionBar"><item name="android:windowTranslucentNavigation">true</item><item name="android:windowTranslucentStatus">true</item><!-- 设置statusBarColor 为透明--><item name="android:statusBarColor">@android:color/transparent</item></style>

效果如下:

Android 6.0 + 实现状态栏字色和图标浅黑色

使用沉浸式的时候会遇到一个问题,那就是Android 系统状态栏的字色和图标颜色为白色,当我的主题色或者图片接近白色或者为浅色的时候,状态栏上的内容就看不清了。 这个问题在Android 6.0的时候得到了解决。Android 6.0 新添加了一个属性SYSTEM_UI_FLAG_LIGHT_STATUS_BAR

添加如下代码:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);}

除了在代码中添加以外,还可以直接在主题中使用属性:

<style name="MDTheme" parent="Theme.Design.Light.NoActionBar"><item name="android:windowTranslucentStatus">false</item><item name="android:windowDrawsSystemBarBackgrounds">true</item><item name="android:statusBarColor">@android:color/holo_red_light</item><!-- Android 6.0以上 状态栏字色和图标为浅黑色--><item name="android:windowLightStatusBar">true</item></style>

注意:主题要放在values-v23文件夹下

参考以下文章

Android关于沉浸式状态栏总结

沉浸式状态栏工具类:/laobie/StatusBarUtil

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。