Android 沉浸式状态栏

article/2025/8/24 3:54:28

文章目录

  • Android 沉浸式状态栏
    • 前提
    • 情况一:使用FrameLayout
    • 情况二:使用CoordinatorLayout
    • fitsSystemWindows属性原理
    • 情况三:在CoordinatorLayout中添加子控件
      • 问题:
      • 解决:
    • 情况四:使用FrameLayout实现沉浸式效果
    • 颜色相近时,修改状态栏图标颜色
    • 代码下载
    • 其他资料

Android 沉浸式状态栏

前提

给Activity或Application设置NoActionBar的主题

<style name="NoActionBarTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar"><!-- Primary brand color. --><item name="colorPrimary">@color/purple_500</item><item name="colorPrimaryVariant">@color/purple_700</item><item name="colorOnPrimary">@color/white</item><!-- Secondary brand color. --><item name="colorSecondary">@color/teal_200</item><item name="colorSecondaryVariant">@color/teal_700</item><item name="colorOnSecondary">@color/black</item><!-- 设置状态栏颜色: --><item name="android:statusBarColor">@android:color/transparent</item>
</style>

情况一:使用FrameLayout

代码如下:

class ImmersionActivity1 : BaseActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_immersion1)window.statusBarColor = Color.TRANSPARENT}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/pink"android:fitsSystemWindows="true"tools:context=".immersion.ImmersionActivity1"></FrameLayout>

效果如下:

在这里插入图片描述

说明:

状态栏部分没有被颜色,说明沉浸式效果没有达到。

情况二:使用CoordinatorLayout

将FrameLayout替换为CoordinatorLayout布局。

代码如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/pink"android:fitsSystemWindows="true"tools:context=".immersion.ImmersionActivity1"></androidx.coordinatorlayout.widget.CoordinatorLayout>

效果如下:

在这里插入图片描述

说明:

状态栏有被颜色,说明沉浸式效果已经达到了。

fitsSystemWindows属性原理

为什么根布局是FrameLayout时,fitsSystemWindows属性不生效,而使用CoordinatorLayout布局时才能生效。

这是因为CoordinatorLayout布局对这个属性进行了处理,其核心代码如下:

private void setupForInsets() {if (Build.VERSION.SDK_INT < 21) {return;}if (ViewCompat.getFitsSystemWindows(this)) {if (mApplyWindowInsetsListener == null) {mApplyWindowInsetsListener =new androidx.core.view.OnApplyWindowInsetsListener() {@Overridepublic WindowInsetsCompat onApplyWindowInsets(View v,WindowInsetsCompat insets) {return setWindowInsets(insets);}};}// 核心代码ViewCompat.setOnApplyWindowInsetsListener(this, mApplyWindowInsetsListener);// 核心代码setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);} else {ViewCompat.setOnApplyWindowInsetsListener(this, null);}
}

情况三:在CoordinatorLayout中添加子控件

问题:

根布局为CoordinatorLayout,子控件Button和ImageView没有延伸到状态栏区域。

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/pink"android:fitsSystemWindows="true"tools:context=".immersion.ImmersionActivity3"><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="hello" /><ImageViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:fitsSystemWindows="true"android:scaleType="fitXY"android:src="@drawable/a" /></androidx.coordinatorlayout.widget.CoordinatorLayout>

在这里插入图片描述

解决:

可以使用CollapsingToolbarLayout控件解决。

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/pink"android:fitsSystemWindows="true"tools:context=".immersion.ImmersionActivity3"><com.google.android.material.appbar.CollapsingToolbarLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:fitsSystemWindows="true"><ImageViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:fitsSystemWindows="true"android:scaleType="fitXY"android:src="@drawable/a" /></com.google.android.material.appbar.CollapsingToolbarLayout><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="hello" /></androidx.coordinatorlayout.widget.CoordinatorLayout>

在这里插入图片描述

情况四:使用FrameLayout实现沉浸式效果

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/frame_layout"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".immersion.ImmersionActivity4"><ImageViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:scaleType="fitXY"android:src="@drawable/a" /><Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="hello" /></FrameLayout>
override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_immersion4)window.statusBarColor = Color.TRANSPARENTval frameLayout: FrameLayout = findViewById(R.id.frame_layout)val button: Button = findViewById(R.id.button)//沉浸式效果:frameLayout.systemUiVisibility =SYSTEM_UI_FLAG_LAYOUT_STABLE or SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN//状态栏遮挡问题:ViewCompat.setOnApplyWindowInsetsListener(button, object : OnApplyWindowInsetsListener {override fun onApplyWindowInsets(view: View,insets: WindowInsetsCompat): WindowInsetsCompat {val layoutParams = view.layoutParams as FrameLayout.LayoutParamslayoutParams.topMargin = insets.systemWindowInsetTopreturn insets}})
}

在这里插入图片描述

颜色相近时,修改状态栏图标颜色

当状态栏图标的颜色和背景图颜色非常接近时,会导致部分内容看不清的情况。

这事可以借助Palette库识别状态栏区域的颜色,如果是浅色将状态栏图标的颜色改为黑色,否则改为白色。

添加依赖库

implementation 'androidx.palette:palette:1.0.0'

工具类:

/*** 状态栏工具类*/
object StatusBarUtils {/*** 获取状态栏高度*/fun getStatusBarHeight(context: Context): Int {var result = 0val resourceId = context.resources.getIdentifier("status_bar_height", "dimen", "android")if (resourceId > 0) {result = context.resources.getDimensionPixelSize(resourceId)}return result}/*** 亮色状态栏,图片和文字是黑色的*/fun setLightStatusBar(activity: Activity) {val flags = activity.window.decorView.systemUiVisibilityactivity.window.decorView.systemUiVisibility = flags or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR}/*** 暗色状态栏,图片和文字是白色的*/fun setDarkStatusBar(activity: Activity) {val flags =activity.window.decorView.systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BARactivity.window.decorView.systemUiVisibility =flags xor View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR}
}
/*** 屏幕工具类*/
object ScreenUtils {/*** 获取屏幕宽度*/fun getScreenWidth(context: Context): Int {val displayMetrics = context.resources.displayMetricsreturn displayMetrics.heightPixels}
}

代码实现:

class ImmersionActivity5 : BaseActivity() {private lateinit var imageView: ImageViewoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_immersion5)val btnDarkImage = findViewById<Button>(R.id.btn_dark_image)val btnLightImage = findViewById<Button>(R.id.btn_light_image)imageView = findViewById(R.id.imageView)btnDarkImage.setOnClickListener {setImageByResource(R.drawable.dark_image)}btnLightImage.setOnClickListener {setImageByResource(R.drawable.light_image)}setImageByResource(R.drawable.light_image)}private fun setImageByResource(@DrawableRes imageResource: Int) {val bitmap = BitmapFactory.decodeResource(resources, imageResource)imageView.setImageBitmap(bitmap)detectBitmapColor(bitmap)}/*** 检测Bitmap颜色*/private fun detectBitmapColor(bitmap: Bitmap) {val colorCount = 5val left = 0val top = 0val right = ScreenUtils.getScreenWidth(this)val bottom = StatusBarUtils.getStatusBarHeight(this)Palette.from(bitmap).maximumColorCount(colorCount).setRegion(left, top, right, bottom).generate(object : Palette.PaletteAsyncListener {override fun onGenerated(palette: Palette?) {var mostPopularSwatch: Palette.Swatch? = nullif (palette != null) {for (swatch in palette.swatches) {if (mostPopularSwatch == null|| swatch.population > mostPopularSwatch.population) {mostPopularSwatch = swatch}}}mostPopularSwatch?.let { swatch ->val luminance = ColorUtils.calculateLuminance(swatch.rgb)if (luminance < 0.5) {StatusBarUtils.setDarkStatusBar(mActivity)} else {StatusBarUtils.setLightStatusBar(mActivity)}}}})}
}

效果:

点击“切换暗色图片”按钮:

在这里插入图片描述

点击“切换亮色图片”按钮:

在这里插入图片描述

代码下载

其他资料

优秀博客推荐

第三方框架推荐(ImmersionBar)

第三方框架推荐(UltimateBarX)


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

相关文章

Android实现沉浸式状态栏效果

关于沉浸式状态栏&#xff0c;给大家推荐一个非常好的博文android标题栏、状态栏图标文字颜色及背景动态变化 另外说明下&#xff0c;沉浸式状态栏的实现仅适用于 android 4.4及以上版本&#xff0c;4.4以下的就不要想了。 1. 实现秀明状态栏常规方法 //是否使用特殊的标题栏背…

适配“沉浸式”状态栏

传送门&#xff1a; fitSystemWindow属性的作用 http://blog.csdn.net/wangxp423/article/details/79564244 fitSystemWindow属性实战 http://blog.csdn.net/wangxp423/article/details/79566465 上两篇我们讲了fitSystemWindows实现沉浸式状态栏&#xff0c;本篇主要讲解适…

Android 实现沉浸式状态栏(包含顶部栏吸顶Layout CoordinatorLayout实现沉浸式状态栏)

前言 Android状态栏默认是固定的黑底白字&#xff0c;这肯定是不被伟大的设计师所喜爱的&#xff0c;更有甚者&#xff0c;某些时候设计希望内容能够延伸到状态栏上部&#xff08;例如顶部是大图的情况&#xff09;。所幸的是随着Android版本的迭代&#xff0c;开发者对状态栏…

Android实现ImmersionBar沉浸式状态栏

&#xff08;一&#xff09;效果图 &#xff08;二&#xff09;实现步骤&#xff1a; 1、在build.gradle中加上 implementation com.gyf.barlibrary:barlibrary:2.3.0 2、设置页面为全屏 将上图中的 <style name"AppTheme" parent"Theme.AppCompat.Light.…

Android沉浸式状态栏实现

首先创建一个BaseActivity或者BaseFragment&#xff0c; 后面需要沉浸式状态的继承BaseActivity或BaseFragment, 然后在XML文件中添加想设置的状态栏背景颜色&#xff0c;以下两句代码 android:background"#1677FE" android:fitsSystemWindows“true” BaseActivity代…

一个Android沉浸式状态栏上的黑科技

本文同步发表于我的微信公众号&#xff0c;扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注&#xff0c;每个工作日都有文章更新。 说起来&#xff0c;在不知不觉中&#xff0c;我竟然凑成了这沉浸式状态栏三部曲。 其实最开始的时候&#xff0c;我主要是因为工作上的原因想…

Android 实现沉浸式状态栏

上一篇文章将Android 实现变色状态栏我们实现了变色的状态栏&#xff0c;也介绍了沉浸式状态栏和透明状态栏的区别&#xff0c;这篇文章我们实现沉浸式状态栏。 沉浸式状态栏的来源就是很多手机用的是实体按键&#xff0c;没有虚拟键&#xff0c;于是开了沉浸模式就只有状态栏消…

Android 沉浸式状态栏攻略 让你的状态栏变色吧

转载请标明出处&#xff1a; http://blog.csdn.net/lmj623565791/article/details/48649563&#xff1b; 本文出自:【张鸿洋的博客】 一、概述 近期注意到QQ新版使用了沉浸式状态栏&#xff0c;ok&#xff0c;先声明一下&#xff1a;本篇博客效果下图&#xff1a; 关于这个状…

Android 最新实现沉浸式状态栏的效果

博主前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住也分享一下给大家&#xff0c; &#x1f449;点击跳转到网站 什么是状态栏: 是指手机屏幕最顶上&#xff0c;显示中国移动、安全卫士、电量、网速等等&#xff0c;在手…

Android 沉浸式状态栏完美解决方案

国内很多类似的文章, 我只想说一个字, 真tm乱! 我看不懂… 评论里面 全在说无效什么的 (我试了也无效, 好厉害的样子) 不废话,回到正题, 首先贴上一个众所周知的库 SystemBarTint 我只要这个类 https://github.com/jgilfelt/SystemBarTint/blob/master/library/src/com/readys…

Android---沉浸式状态栏

Android—沉浸式状态栏 我们的征程是星辰大海&#xff0c;而非人间烟尘 文章目录 Android---沉浸式状态栏去掉标题栏效果 引入依赖沉浸状态栏颜色沉浸状态栏图片 去掉标题栏 首先去掉对应主题下面的Android自带的ActionBar&#xff0c;只需要在对应主题下面加NoActionBar 效果 …

史上最完美的Android沉浸式状态导航栏攻略

前言 最近我在小破站开发一款新App&#xff0c;叫高能链。我是一个完美主义者&#xff0c;所以不管对架构还是UI&#xff0c;我都是比较抠细节的&#xff0c;在状态栏和导航栏沉浸式这一块&#xff0c;我还是踩了挺多坑&#xff0c;费了挺多精力的。这次我将我踩坑&#xff0c…

Android设置“沉浸式状态栏”的方法

Android系统界面构成 Android系统界面由状态栏、ActionBar和导航栏组成&#xff0c;如下图所示&#xff1a; “沉浸式状态栏”的界面显示效果 沉浸式状态栏&#xff0c;或叫“透明状态栏”&#xff0c;显示效果如下图所示&#xff1a; 实现沉浸式状态栏的步骤 一、添加StatusB…

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

Android沉浸式状态栏&#xff08;透明系统状态栏&#xff09;的目的&#xff1a;顶部系统状态栏和App的导航栏一体化&#xff0c;不给用户突兀的感觉&#xff0c;使用户把更多的视角留在我们的App上。 沉浸式状态栏的兼容情况 Android版本透明状态栏<4.44.4-5.0✓>5.0✓…

沉浸式状态栏

沉浸式状态栏 简单介绍 沉浸式状态栏其实是对沉浸模式(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…