前置知识
- Goodle 从 RenderScript 迁移
- GitHub renderscript-intrinsics-replacement-toolkit
- Google 窗口模糊
- 掘金 ❤️Android 12 高斯模糊-RenderEffect❤️
概述
高斯模糊主要应用于: 对单个View的内容进行模糊, 对Window的背景进行模糊, 对Window后面的所有内容进行模糊.
1. 对单个View的内容进行模糊
- 如果以 Android 12(API 级别 31)及更高版本为目标平台,直接使用系统内置 RenderEffect 类
- 否则需要使用 renderscript-intrinsics-replacement-toolkit

- 使用 RenderEffect 设置View的模糊效果
-
View.setRenderEffect(RenderEffect.createBlurEffect(radiusX, radiusY, Shader.TileMode))
-
View.setRenderEffect(null) 会取消模糊效果
class RenderEffectActivity : AppCompatActivity() { lateinit var img: ImageView lateinit var tv: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_render_effect) img = findViewById(R.id.img) img.setOnClickListener{ img.setRenderEffect(null) } tv = findViewById(R.id.tv) tv.setOnClickListener{ tv.setRenderEffect(null) } } private val radius: FloatArray = floatArrayOf(1.0F, 2.0F, 4.0F, 8.0F, 16.0F) private var index: Int = -1 fun showRenderEffect(view: View) { index = (index+1) % radius.size img.setRenderEffect(RenderEffect.createBlurEffect(radius[index], radius[index], Shader.TileMode.MIRROR)) tv.setRenderEffect(RenderEffect.createBlurEffect(radius[index], radius[index], Shader.TileMode.MIRROR)) } }
-
2. 对Window的背景进行模糊
- 不要设置window.attributes.blurBehindRadius即可
- 其他代码保持和'3. 对Window后面的所有内容进行模糊'保持一致即可
//window.attributes.blurBehindRadius 用于设置Activity的窗口后面所有内容的模糊
//window.attributes.blurBehindRadius = mBlurBehindRadius;
- 运行截图
3. 对Window后面的所有内容进行模糊.
-
2和3使用的注意事项:

-
实际代码
//Activity声明 <activity android:name="com.example.windowblur.BlurActivity" android:exported="true" android:theme="@style/Theme.WindowBlur" /> //Activity使用的主题 <style name="Theme.WindowBlur" parent="Theme.MaterialComponents.Dialog"> <item name="android:windowIsTranslucent">true</item> </style> //Activity使用的布局 activity_blur.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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="300dp" android:layout_height="300dp" tools:context="com.example.windowblur.BlurActivity" android:layout_gravity="center" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:textSize="32sp" android:textColor="#000000" android:padding="32dp" android:text="铜镜映无邪" android:textStyle="bold" /> </RelativeLayout> //支持窗口模糊 和 不支持窗口模糊 将要使用的窗口背景drawable //window_background_with_blur.xml //半透明红色 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#32FF0000" /> <corners android:radius="16dp" /> </shape> //window_background_no_blur.xml //半透明绿色 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#3200FF00" /> <corners android:radius="16dp" /> </shape>class BlurActivity : AppCompatActivity() { private val mBackgroundBlurRadius = 100 private var mBackgroundDrawableWithBlur: Drawable? = null private var mBackgroundDrawableNoBlur: Drawable? = null private val mBlurBehindRadius = 20 private val mDimAmountWithBlur = 0.1f private val mDimAmountNoBlur = 0.6f private val mCrossWindowBlurEnabledListener: Consumer<Boolean> = Consumer<Boolean> { enabled -> Log.i(TAG_TRACK, "mCrossWindowBlurEnabledListener. enabled:$enabled") window.setBackgroundDrawable( if (enabled) mBackgroundDrawableWithBlur else mBackgroundDrawableNoBlur ) window.setDimAmount(if (enabled) mDimAmountWithBlur else mDimAmountNoBlur) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_blur) mBackgroundDrawableWithBlur = resources.getDrawable( R.drawable.window_background_with_blur ) mBackgroundDrawableNoBlur = resources.getDrawable( R.drawable.window_background_no_blur ) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { window.addFlags( WindowManager.LayoutParams.FLAG_BLUR_BEHIND ) //window.attributes.blurBehindRadius 用于设置Activity的窗口后面所有内容的模糊 window.attributes.blurBehindRadius = mBlurBehindRadius; //window.setBackgroundBlurRadius 用于设置Activity的窗口自身的背景模糊 window.setBackgroundBlurRadius(mBackgroundBlurRadius) window.decorView.addOnAttachStateChangeListener( object : View.OnAttachStateChangeListener { override fun onViewAttachedToWindow(v: View?) { Log.i(TAG_TRACK, "onViewAttachedToWindow. addCrossWindowBlurEnabledListener.") //添加监听 windowManager.addCrossWindowBlurEnabledListener( mCrossWindowBlurEnabledListener ) } override fun onViewDetachedFromWindow(v: View?) { Log.i(TAG_TRACK, "onViewDetachedFromWindow. removeCrossWindowBlurEnabledListener.") //移除监听 windowManager.removeCrossWindowBlurEnabledListener( mCrossWindowBlurEnabledListener ) } }) } window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); } } -
红米手机实际运行截图
