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

相关文章

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

PHP应用中处理限流和API节流的最佳实践

《PHP应用中处理限流和API节流的最佳实践》限流和API节流对于确保Web应用程序的可靠性、安全性和可扩展性至关重要,本文将详细介绍PHP应用中处理限流和API节流的最佳实践,下面就来和小编一起学习... 目录限流的重要性在 php 中实施限流的最佳实践使用集中式存储进行状态管理(如 Redis)采用滑动

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

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

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

MySQL分库分表的实践示例

《MySQL分库分表的实践示例》MySQL分库分表适用于数据量大或并发压力高的场景,核心技术包括水平/垂直分片和分库,需应对分布式事务、跨库查询等挑战,通过中间件和解决方案实现,最佳实践为合理策略、备... 目录一、分库分表的触发条件1.1 数据量阈值1.2 并发压力二、分库分表的核心技术模块2.1 水平分

Android协程高级用法大全

《Android协程高级用法大全》这篇文章给大家介绍Android协程高级用法大全,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习吧... 目录1️⃣ 协程作用域(CoroutineScope)与生命周期绑定Activity/Fragment 中手

SpringBoot通过main方法启动web项目实践

《SpringBoot通过main方法启动web项目实践》SpringBoot通过SpringApplication.run()启动Web项目,自动推断应用类型,加载初始化器与监听器,配置Spring... 目录1. 启动入口:SpringApplication.run()2. SpringApplicat

Java整合Protocol Buffers实现高效数据序列化实践

《Java整合ProtocolBuffers实现高效数据序列化实践》ProtocolBuffers是Google开发的一种语言中立、平台中立、可扩展的结构化数据序列化机制,类似于XML但更小、更快... 目录一、Protocol Buffers简介1.1 什么是Protocol Buffers1.2 Pro