Android中毛玻璃效果的实践

2024-03-03 10:20

本文主要是介绍Android中毛玻璃效果的实践,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

问题背景:需要在一个Activity内实现一个dialog,并让dialog周围的半透明遮罩变为高斯模糊效果。正常接入组件库后,TV上面未出现高斯模糊效果

实际尝试的方案(方案1和2为Activity内直接写布局,方案3为空activity加载组件弹窗):
方案1:Activity利用

	<item name="android:windowIsTranslucent">false</item><item name="android:colorBackground">@android:color/transparent</item>

可以实现模糊度效果,但是存在致命问题:Activity弹出后,MainActivity直接被透明了,看到了桌面

方案2:利用

<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">?attr/colorPrimarySurface</item> 		

可是避免方案1的问题,但是模糊度没办法做到和组件一样,只能通过调节模糊比例,做到近似效果

方案3:直接在activity内对接公共组件库dialog,目前在TV上无法实现高斯模糊效果
通过修改activity主题后,
使用方案1主题,可实现毛玻璃效果,但出现的问题与方案1一致
使用方案2主题,无毛玻璃效果

通过以上尝试,可以判断出activity对接组件dialog毛玻璃不生效,跟使用的主题有较大关系,但是首页被透明显示的问题未查到根本原因,只知道与

<item name="android:colorBackground">@android:color/transparent</item>

这个属性设置有很大关系

方案2实现方式:

    override fun onCreate(savedInstanceState: Bundle?) {lifecycle.addObserver(BackgroundBlurUtil(window))super.onCreate(savedInstanceState)}
class BackgroundBlurUtil(private var window: Window?,private val mBackgroundBlurRadius: Int = 20,    //窗口背景高斯模糊程度,数值越高越模糊且越消耗性能private val mBlurBehindRadius: Int = 20,        //窗口周边背景高斯模糊程度private val mDimAmountWithBlur: Float = 0f,    //根据窗口高斯模糊功能是否开启来设置窗口周边暗色的程度
): DefaultLifecycleObserver {override fun onCreate(owner: LifecycleOwner) {super.onCreate(owner)initBlur()}override fun onDestroy(owner: LifecycleOwner) {super.onDestroy(owner)window = null}/*** 更新窗口的高斯模糊效果*/private fun updateWindowForBlurs() {//设置背景模糊程度if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {LogUtils.d("BackgroundBlurUtil", "updateWindowForBlurs")window?.setBackgroundBlurRadius(mBackgroundBlurRadius)//设置背景周边模糊程度window?.attributes?.blurBehindRadius = mBlurBehindRadius//调整背景周边昏暗的程度window?.setDimAmount(mDimAmountWithBlur)//让上面的高斯模糊效果生效window?.attributes = window?.attributes}}/*** 设置一个窗口视图状态监听者,监听窗口视图是否可见以便是否更新窗口模糊的状态*/private fun setupWindowBlurListener(){val windowBlurEnabledListener = Consumer { _: Boolean? ->updateWindowForBlurs()}window?.decorView?.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener{override fun onViewAttachedToWindow(v: View) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {window?.windowManager?.addCrossWindowBlurEnabledListener(windowBlurEnabledListener)}}override fun onViewDetachedFromWindow(v: View) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {window?.windowManager?.removeCrossWindowBlurEnabledListener(windowBlurEnabledListener)}}})}private fun initBlur(){window?.run {//允许背景模糊,也可以通过样式属性R.attr#windowBlurBehindEnabled来实现addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND)// 允许背景变暗,也可以通过样式属性R.attr#backgroundDimEnabled来实现addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)}// 高斯模糊监听setupWindowBlurListener()}
}

关于主题:
继承基础主题后,实现如下两个属性:

<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">?attr/colorPrimarySurface</item>

主题属性介绍:
windowIsTranslucent:
windowIsTranslucent 通常用于创建半透明的对话框或菜单,是控制窗口是否半透明。 设置为 true 时,窗口将是半透明的,窗口后面的内容也将是可见的。设置为 false 时,窗口将是不透明的,窗口后面的内容将不可见。
windowIsTranslucent 主题属性在 Android 4.0(API 14)及更高版本上可以生效,需要与 windowBackground 属性一起使用,windowBackground 属性用于指定窗口的背景颜色

还有另外一个方案:将windowIsTranslucent设置为false,但是设置colorBackground和windowBackground为透明,再设置布局中的背景色,但是这个方案出现了底层activity完全透明的现象,具体原因不得而知

	<item name="android:windowIsTranslucent">false</item><item name="android:colorBackground">@android:color/transparent</item>

参考:
Android12窗口模糊(一)在Activity和Dialog中实现高斯模糊效果
android13 FLAG_BLUR_BEHIND 壁纸高斯模糊,毛玻璃背景方案设计

这篇关于Android中毛玻璃效果的实践的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

全面掌握 SQL 中的 DATEDIFF函数及用法最佳实践

《全面掌握SQL中的DATEDIFF函数及用法最佳实践》本文解析DATEDIFF在不同数据库中的差异,强调其边界计算原理,探讨应用场景及陷阱,推荐根据需求选择TIMESTAMPDIFF或inte... 目录1. 核心概念:DATEDIFF 究竟在计算什么?2. 主流数据库中的 DATEDIFF 实现2.1

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

Android ClassLoader加载机制详解

《AndroidClassLoader加载机制详解》Android的ClassLoader负责加载.dex文件,基于双亲委派模型,支持热修复和插件化,需注意类冲突、内存泄漏和兼容性问题,本文给大家介... 目录一、ClassLoader概述1.1 类加载的基本概念1.2 android与Java Class

Spring WebFlux 与 WebClient 使用指南及最佳实践

《SpringWebFlux与WebClient使用指南及最佳实践》WebClient是SpringWebFlux模块提供的非阻塞、响应式HTTP客户端,基于ProjectReactor实现,... 目录Spring WebFlux 与 WebClient 使用指南1. WebClient 概述2. 核心依

MyBatis-Plus 中 nested() 与 and() 方法详解(最佳实践场景)

《MyBatis-Plus中nested()与and()方法详解(最佳实践场景)》在MyBatis-Plus的条件构造器中,nested()和and()都是用于构建复杂查询条件的关键方法,但... 目录MyBATis-Plus 中nested()与and()方法详解一、核心区别对比二、方法详解1.and()

Spring Boot @RestControllerAdvice全局异常处理最佳实践

《SpringBoot@RestControllerAdvice全局异常处理最佳实践》本文详解SpringBoot中通过@RestControllerAdvice实现全局异常处理,强调代码复用、统... 目录前言一、为什么要使用全局异常处理?二、核心注解解析1. @RestControllerAdvice2

Spring事务传播机制最佳实践

《Spring事务传播机制最佳实践》Spring的事务传播机制为我们提供了优雅的解决方案,本文将带您深入理解这一机制,掌握不同场景下的最佳实践,感兴趣的朋友一起看看吧... 目录1. 什么是事务传播行为2. Spring支持的七种事务传播行为2.1 REQUIRED(默认)2.2 SUPPORTS2

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

MySQL 中 ROW_NUMBER() 函数最佳实践

《MySQL中ROW_NUMBER()函数最佳实践》MySQL中ROW_NUMBER()函数,作为窗口函数为每行分配唯一连续序号,区别于RANK()和DENSE_RANK(),特别适合分页、去重... 目录mysql 中 ROW_NUMBER() 函数详解一、基础语法二、核心特点三、典型应用场景1. 数据分

深度解析Spring AOP @Aspect 原理、实战与最佳实践教程

《深度解析SpringAOP@Aspect原理、实战与最佳实践教程》文章系统讲解了SpringAOP核心概念、实现方式及原理,涵盖横切关注点分离、代理机制(JDK/CGLIB)、切入点类型、性能... 目录1. @ASPect 核心概念1.1 AOP 编程范式1.2 @Aspect 关键特性2. 完整代码实