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

article/2025/8/24 8:20:31

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

沉浸式状态栏的兼容情况

Android版本透明状态栏
<4.4×
4.4-5.0
>=5.0
Android版本黑白字符状态栏
<6.0×
>=6.0

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

效果如下:
Alt
效果如上图,可以看出,沉浸式的效果是出来了,但是也有一个问题,我们的标题栏和状态栏重叠了,相当于整个布局上移了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。
添加上述代码后,效果如下:
Alt
通过以上就可以实现Android 4.4 上的沉浸式状态栏

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

小结: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才用这个)

效果如下:
Alt

当然也可以直接在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>

效果如下:
Alt

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

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

Alt

添加如下代码:

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关于沉浸式状态栏总结

沉浸式状态栏工具类:https://github.com/laobie/StatusBarUtil

 

 

 

 

 

 


http://chatgpt.dhexx.cn/article/qbV0bpHm.shtml

相关文章

沉浸式状态栏

沉浸式状态栏 简单介绍 沉浸式状态栏其实是对沉浸模式(Immersive Mode)在状态栏上的体现,即让状态栏变透明,或者是在打游戏和看视频时彻底隐藏起状态栏,让用户拥有良好的体验。 比如说我们看视频,状态栏隐藏后视频的观看会更加完整,下图就是看视频时的截图,可以看到当…

Android沉浸式状态栏,看完这篇就够了!

背景 之前做过Android沉浸式状态栏的相关需求&#xff0c;但是一直忙于工作&#xff0c;没时间系统的整理下沉浸式相关的知识&#xff0c;所以今天抽出时间&#xff0c;写一篇 Android沉浸式状态栏的文章。 何为沉浸式 沉浸式就是要给用户提供完全沉浸的体验&#xff0c;使用…

图片预览与下载

后端返回base64进行图片的预览和下载下载 有一个图片预览的接口。后端返回的值长这个样子 1、预览 如果要在线预览的话&#xff0c;代码需要这样写放入img的src this.imgPreviewBaseUrl data:image/png;base64, res.data标签中就是这样的 2、下载 图片预览的这样的返…

vue 实现图片预览

vue实现图片预览 现在很多的项目里面图片展示缩略图,然后点击实现图片预览,放大的功能 最近我的项目里面就遇见了这么个场景,我选用了插件进行处理 下面说下实现步骤 1、首先安装插件 npm install vue-photo-preview --save插件地址 2、在main.js里面引入,全局使用 impor…

图片预览器

此预览器&#xff0c;一次只能翻页十张图片&#xff0c;开发人员可根据自己需要&#xff0c;修改前台代码。 页面代码 <% Page Language"C#" AutoEventWireup"true" CodeBehind"UpFilesAndPreview.aspx.cs" Inherits"WebFramework.Comm…

v-viewer图片预览

安装 npm install v-viewer引入 import Viewer from v-viewer import viewerjs/dist/viewer.css Vue.use (Viewer, {defaultOptions: {navbar: true,toolbar: false,movable: false,title: false,zoomable: true,scalable: true,transition: true} })使用 方法一&#xff1a…

vue2图片预览插件

文章目录 学习链接准备工作准备图片与基础的样式PrevImg.vueApp.vue静态效果 封装插件修改PrevImg.vue定义插件逻辑main.js中应用此插件App.vue中使用此插件 图片预览列表修改App.vue修改插件逻辑修改PrevImg.vue 学习链接 vue插件开发实例-图片预览插件 vue2-pre-img-plugin的…

vue 图片预览插件

vue 图片预览插件 步骤 1、先安装依赖 npm install v-viewer --save2、main.js内引用并注册调用 //main.js import Viewer from v-viewer import viewerjs/dist/viewer.cssVue.use(Viewer); Viewer.setDefaults({Options: { "inline": true, "button": …

Vue3图片预览(Image)

本图片预览组件主要包括以下功能&#xff1a; 展示图片时&#xff0c;可设置鼠标悬浮时的预览文本&#xff1b;图像无法加载时要显示的描述&#xff1b;自定义图像高度和宽度&#xff1b;设置图像如何适应容器高度和宽度&#xff08; fill(填充) | contain(等比缩放包含) | cov…

Vue实现图片预览和缩放功能

使用v-viewer插件即可实现图片预览和缩放功能。&#xff08;v-viewer是一款支持vue项目中的图片浏览组件&#xff0c;它支持图片旋转、缩放、翻转等操作&#xff0c;支持配置化.非常强大&#xff09; 安装依赖 执行命令&#xff1a; npm install v-viewer --save 引入并使用…

图片上传预览功能

大多时候我们上传图片&#xff0c;都是直接上传到服务器上&#xff0c;然后返回图片资源所在服务器的路径&#xff0c;然后页面根据这个路径&#xff0c;给图片一个src 属性就能看到图片了。 但是&#xff0c;这样会有一个弊端&#xff1a;如果客户对自己上传的图片不满意&am…

uniapp 图片预览实现

uniapp 图片预览实现 提示&#xff1a;下面案例可供参考 一、app端 使用 uni.previewImage 进行图片预览 可去 uniapp官网 查看具体使用:(https://uniapp.dcloud.net.cn/api/media/image.html#unipreviewimageobject) 二、具体使用如下&#xff08;示例&#xff09;&#xf…

Android中点击图片进行图片预览功能的实现(ImagePreview图片预览工具库)

因为需求&#xff0c;对于轮播图进行一个点击预览的功能&#xff0c;看了好多的文章&#xff0c;都没有弄出来&#xff0c;还是多亏了昊昊猿博主 点击查看原文 终于把它搞定啦。 这里的话是使用ImagePreview&#xff0c;一个非常好用的图片预览工具库&#xff08;还可以实现双…

Vue实现图片预览(Viewer.js)

Viewer.js viewer.js是一款开源的图片预览插件&#xff0c;功能十分强大: 支持移动设备触摸事件 支持响应式 支持放大/缩小 支持旋转&#xff08;类似微博的图片旋转&#xff09; 支持水平/垂直翻转 支持图片移动 支持键盘 支持全屏幻灯片模式&#xff08;可做屏保&#xff0…

前端图片预览怎么做?Vue

选择的图片文件&#xff0c;要给到img标签上纯前端的预览 让用户更近一步看到自己选择的头像 因为img的标签的src的值只能是以下两个 1、只能是图片的“链接地址”&#xff08;外链http://开头&#xff0c;图片文件相对路径&#xff09;(不能发给后台)因为第一种转成http是存…

点击图片实现大图预览

实现点击图片预览 这次主要是在table表格里能够实现&#xff0c;点击里面的图片实现大图预览的效果&#xff0c;直接找的现成的轮子&#xff0c;用在项目里。这里主要是讲讲用viewer组件实现点击图片预览&#xff0c;用的组件&#xff0c;只需在本地安装或者引入。 先看一下&…

ImagePreview 图片预览 的使用​

一、ImagePreview 图片预览 的使用 ImagePreview 是一个函数&#xff08;必须使用按需到处&#xff09;&#xff0c;调用函数后会直接在页面中展示图片预览界面。 // 实现图片预览 import { ImagePreview } from vant 二、处理图片点击预览 思路&#xff1a; 1、从文章内容中…

图片预览(原生js实现)

功能描述 很多网站都是使用浏览器自带图片浏览功能&#xff0c;但看起来很low&#xff0c;想手动实现图片预览功能&#xff0c;点击图片弹出大图预览框在屏幕中间显示&#xff0c;根据图片宽高自适应屏幕大小 效果图 具体代码实现 页面preview.html <!DOCTYPE html> …

图片预览的两种实现方式

做用户头像上传等类似功能的时候&#xff0c;经常会有预览选中图片的需求。在这里介绍两种实现预览的方式。 1.转化为base64格式 通过一种异步文件读取机制FileReader实现。具体步骤是&#xff1a; 创建FileReader对象调用readAsDataURL函数读取文件内容监听FileReader创建的…

CVTE 面试的两道算法题

下了班立马赶往深圳北站&#xff0c;下着大雨又坐过了站&#xff0c;着急地跑向对面的站牌&#xff0c;匆忙间搞得满头大汗。好不容易坐上了高铁&#xff0c;休息片刻&#xff0c;终于有时间整理一下前两天面试CVTE 时遇到的两道算法题。 1. 在数组中寻找和为固定值的两个数字…