Android 自动取色并设置沉浸式状态栏

2023-10-09 07:20

本文主要是介绍Android 自动取色并设置沉浸式状态栏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

作者:stars-one
链接:https://www.cnblogs.com/stars-one/p/16632818.html

设置沉浸式状态栏

1.添加依赖

这里,是使用了一个Android的工具开源库来实现了功能,首先需要依赖

// Android的工具类   https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/README-CN.md
implementation 'com.blankj:utilcodex:1.31.0'

2.使用

工具类中有个BarUtils的类,里面提供了对应状态栏和导航栏的对应方法,如设置透明状态栏,设置状态栏颜色等

下面,我们就是用到其中的setStatusBarColor()方法

APP的原图为这样

842ba1eef77dc8b39896a34c246aad6a.png

我们下面需要设置沉浸式的状态栏

使用以下方法:

BarUtils.setStatusBarColor(this, ColorUtils.getColor(R.color.design_default_color_primary))

ColorUtils也是工具库中的一个工具类,通过它可以拿到定义到color.xml中的方法

a4cef8376eb3f9af72930d6a98e45e62.png

我们可以看到,颜色是变了,但是布局似乎被ActionBar遮挡住了一部分

这个时候有以下的解决方法:

在你的Activity对应的布局中加上android:fitsSystemWindows="true"的属性即可解决

如下图所示

f3b7ea64bc1b1ce91bb7269003c1ee74.png

当然,这样做的话会比较繁琐,我们可以考虑使用代码的方式来设置

val contentParent = findViewById(android.R.id.content)
contentParent.getChildAt(0).fitsSystemWindows = true

效果就出来了:

95f28cbdb61fbc1737f08c3d5b664f2a.png

但细看的话,觉得还是看出ActionBar的边界,我们可以考虑使用setStatusBarColor()另一个参数方法

BarUtils.setStatusBarColor(this, ColorUtils.getColor(R.color.design_default_color_primary),true)

效果比之前的要好些:

39ab539535d355b64da66993db529e62.png

实际上,这个的传参的isDecor代表了两种实现沉浸式状态栏的方法

  • true,则是往DecorView添加状态栏,

  • false,则是往ContentView中添加状态栏

所以,这里我个人是比较推荐DecorView,因为显示的效果比较好

3.补充-主题为NoActionBar被遮挡问题解决

在设置主题为NoActionBar之后,会发现出现下面的情况

6b2355f2beef2d0bc03547dbf59de2fe.png

其实解决方法如上述一样,只要设置android:fitsSystemWindows="true"或者用代码去设置即可解决,这里不再赘述

设置状态栏亮色或暗色图标

上面,我们只是设置了状态栏的颜色,但是没有设置对应的显示图标,如果你状态栏设置的颜色比较亮的话,这个时候为了方便图标显示,你得将图标变为暗色的图标

那么具体要怎么实现呢?

其实BarUtil还是有提供对应的方法

val color = ColorUtils.getColor(R.color.design_default_color_primary)
BarUtils.setStatusBarColor(this, color)//设置状态栏图标是否为亮色图标BarUtils.setStatusBarLightMode(this, ColorUtils.isLightColor(color))

这里,我们需要判断下颜色是否为亮色,怎么判断呢?

我们上述引用的库中,带有一个工具类ColorUtils,可以通过其isLightColor()方法来判断颜色是否亮色

于是我们两个方法结合起来,就是上面的设置的方法了

PS:如果想要实现导航条颜色也需要变换,可以使用此方法setNavBarColor(),如下代码:

BarUtils.setNavBarColor(this,color)

自动取色

1.添加依赖

自动取色这里是用到了另外一个开源库palette

这个是谷歌官方出的一个库,主要是用来发布获取图片的主色调

implementation 'androidx.palette:palette:1.0.0'//如果是Kotlin,推荐使用这个
implementation 'androidx.palette:palette-ktx:1.0.0'

下面我是Kotlin使用进行说明

2.使用

Palette是从图片Bitmap中进行颜色提取,所以需要我们传一个图片

这里,我们可以直接将当前屏幕的截图Bitmap对象拿到,然后通过Palette去提取对应的颜色特征点即可

截图:

//截图val drawingCache = ScreenUtils.screenShot(this)

ScreenUtils还是上述工具类库中的工具类,方便获取截图Bitmap对象

Plaette用法:

Palette.from(drawingCache).generate {    //具体获得到的颜色特征数据}

实际上,如果不设置如何参数,上述就可以取颜色特征点了,Palette会开启异步线程来执行解析操作,并将最终结果回调到Lambda表达式当中

具体的颜色提取算法是由Palette自己控制的,我们无需关心。反正只需要知道,最终提取出来的这些颜色值都是这个bitmap的指定区域里最具代表性的就可以了。

一般来说,还是推荐设置对应的参数

比如说我们的需求,是要动态取色,那么,这个颜色应该怎么样才比较准确呢?

那当然是直接取状态栏下方的页面数值,这样就比较好的有着沉浸式效果了

那么,这个需要我们就可以setRegion()方法来指定解析这个bitmap对象的哪个区域,其他区域的颜色值对我们来说没有意义

当然,除此之外,我们调用maximumColorCount()方法来告诉Palette一共需要提取多少个颜色特征点。

于是,代码就变为以下:

//先截图,取当前截图的主要色调val drawingCache = ScreenUtils.screenShot(this)Palette.from(drawingCache).maximumColorCount(5).generate {    //取色成功后的异步回调,取主色调it?.let {        val swatches = it.swatches        //便利找寻主色调var mostSwatch :Palette.Swatch?=nullswatches.forEach {            if (mostSwatch != null) {                //population指的是出现最多的颜色if (mostSwatch!!.population < it.population) {mostSwatch = it}} else {mostSwatch = it}}        //设置状态栏为主色调mostSwatch?.let {            val color = it.rgbBarUtils.setStatusBarColor(this, color, true)BarUtils.setStatusBarLightMode(this, ColorUtils.isLightColor(color))            val contentParent: ViewGroup = findViewById(android.R.id.content)contentParent.getChildAt(0).fitsSystemWindows = true}}
}

原理研究

这里,稍微总结下看到的相关知识原理,不追求长篇大论,各位要深入了解可自行搜索资料

关于Activity页面层级问题

首先,我们要了解下对应的层级关系图,如下图所示:

d8e8516c793e0440accac491b2116ff2.png

上述图中,DecorView其实是继承FrameLayout,然后其中包裹一个子View

这个子View是LinearLayout,方向为竖直方向,其内有两个FrameLayout

b7b8154e67e5d0f8a3a5b266a4716b91.png

沉浸式状态栏实现原理

沉浸式状态栏主要实现思路:先将原先的状态栏设置为透明色,之后在父布局一个View来代替状态栏的占位(高度与状态栏的高度一致)

这里的父布局有两种情况,一种是在DecorView中新增一个新的View来代替状态栏的占位,另外一种则是在ContentView中(通过android.R.id.content可以找到)添加View

如果是第二种方法,因为在不同版本中,此布局包含的子View有所区别,所以在高版本会出现状态栏被遮挡的情况

上述这句总结还未验证过,如果说错可以希望在评论区指出

这个时候可以通过设置fitsSystemWindows进行解决

关于fitsSystemWindows属性

上面也是提到了使用android:fitsSystemWindows="true"解决布局状态栏被遮挡问题,实际上,这个属性只是个标识属性,具体要对应的布局去实现

上面意思呢?就比如说,你的Activity布局是FrameLayout,你定义了这个fitsSystemWindows,那么实际上也不会发生偏移,因为FrameLayout布局中没有对此进行适配

实际上的适配工作,就是布局判断下这个标识,然后自动的加上对应的偏移,就形成了上述我们要的效果

具体可以参考郭霖大佬的文章再学一遍android:fitsSystemWindows属性

fitsSystemWindows在ViewGroup中通过dispatchApplyWindowInsets()进行分发给子View

如果dispatchApplyWindowInsets 中把insets.consumeSystemWindowInsets()消费掉, 那么inset事件就无法传递到子View,子View设置fitsSystemWindows=true将会没有反应

View会通过onApplyWindowInsets()消费掉WindowInsets, 当然其要求是父View必须设置fitSystemWindows=false 这样WindowInsets才能传递到子View中进行消费

关注我获取更多知识或者投稿

87147209c8dd166aa0dc065314b18e72.jpeg

ef583d36911966a6f131c6e6d40fe4e4.jpeg

这篇关于Android 自动取色并设置沉浸式状态栏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/171247

相关文章

JAVA实现Token自动续期机制的示例代码

《JAVA实现Token自动续期机制的示例代码》本文主要介绍了JAVA实现Token自动续期机制的示例代码,通过动态调整会话生命周期平衡安全性与用户体验,解决固定有效期Token带来的风险与不便,感兴... 目录1. 固定有效期Token的内在局限性2. 自动续期机制:兼顾安全与体验的解决方案3. 总结PS

Java实现为PDF设置背景色和背景图片

《Java实现为PDF设置背景色和背景图片》在日常的文档处理中,PDF格式因其稳定性和跨平台兼容性而广受欢迎,本文将深入探讨如何利用Spire.PDFforJava库,以简洁高效的方式为你的PDF文档... 目录库介绍与安装步骤Java 给 PDF 设置背景颜色Java 给 PDF 设置背景图片总结在日常的

C#中通过Response.Headers设置自定义参数的代码示例

《C#中通过Response.Headers设置自定义参数的代码示例》:本文主要介绍C#中通过Response.Headers设置自定义响应头的方法,涵盖基础添加、安全校验、生产实践及调试技巧,强... 目录一、基础设置方法1. 直接添加自定义头2. 批量设置模式二、高级配置技巧1. 安全校验机制2. 类型

linux部署NFS和autofs自动挂载实现过程

《linux部署NFS和autofs自动挂载实现过程》文章介绍了NFS(网络文件系统)和Autofs的原理与配置,NFS通过RPC实现跨系统文件共享,需配置/etc/exports和nfs.conf,... 目录(一)NFS1. 什么是NFS2.NFS守护进程3.RPC服务4. 原理5. 部署5.1安装NF

python库pydantic数据验证和设置管理库的用途

《python库pydantic数据验证和设置管理库的用途》pydantic是一个用于数据验证和设置管理的Python库,它主要利用Python类型注解来定义数据模型的结构和验证规则,本文给大家介绍p... 目录主要特点和用途:Field数值验证参数总结pydantic 是一个让你能够 confidentl

Java利用Spire.XLS for Java设置Excel表格边框

《Java利用Spire.XLSforJava设置Excel表格边框》在日常的业务报表和数据处理中,Excel表格的美观性和可读性至关重要,本文将深入探讨如何利用Spire.XLSforJava库... 目录Spire.XLS for Java 简介与安装Maven 依赖配置手动安装 JAR 包核心API介

Android实现图片浏览功能的示例详解(附带源码)

《Android实现图片浏览功能的示例详解(附带源码)》在许多应用中,都需要展示图片并支持用户进行浏览,本文主要为大家介绍了如何通过Android实现图片浏览功能,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

在Android中使用WebView在线查看PDF文件的方法示例

《在Android中使用WebView在线查看PDF文件的方法示例》在Android应用开发中,有时我们需要在客户端展示PDF文件,以便用户可以阅读或交互,:本文主要介绍在Android中使用We... 目录简介:1. WebView组件介绍2. 在androidManifest.XML中添加Interne

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired