Android弹窗背景如何实现模糊效果而非仅设置透明?
实现Android弹窗背景模糊效果的解决方案
嗨,作为Android开发新手能做到这一步已经超棒啦!你现在的弹窗已经实现了透明,但想要背景模糊效果,我给你整理了几种容易上手的方案,你可以根据自己的需求选择:
方案一:Android 12+官方原生模糊(最简单,仅适配高版本)
如果你的应用只需要适配Android 12(API 31)及以上版本,直接用系统自带的模糊API就可以,代码改动非常小:
- 修改
Pop类的onCreate方法,添加模糊设置:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.popup); // 开启背景模糊(仅Android 12+生效) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { getWindow().setBackgroundBlurRadius(20); // 模糊半径,数值越大越模糊,建议15-25之间 getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); } DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); int width = dm.widthPixels; int height = dm.heightPixels; getWindow().setLayout((int)(width*.8),(int)(height*.6)); }
- 确保你的弹窗主题已经设置透明,你的
style.xml已经有相关配置,再补充一个属性:
<style name="AppTheme.Popuptheme"> <item name="android:windowIsTranslucent">true</item> <item name="android:windowCloseOnTouchOutside">true</item> <item name="android:windowBackground">@android:color/transparent</item> <!-- 新增:确保背景完全透明 --> <item name="android:windowNoTitle">true</item> <!-- 可选:去掉弹窗标题栏 --> </style>
方案二:兼容低版本(Android 8.0+)的模糊实现
如果要适配更低版本(比如Android 8.0到11),可以结合FLAG_DIM_BEHIND和RenderScript来实现模糊效果:
步骤1:开启RenderScript支持
在你的app/build.gradle文件中添加以下配置:
android { ... defaultConfig { ... renderscriptTargetApi 33 // 可以设置为你项目的目标API版本 renderscriptSupportModeEnabled true } }
步骤2:创建模糊工具类
新建一个BlurUtils.java文件,封装模糊逻辑:
import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.view.View; import androidx.renderscript.Allocation; import androidx.renderscript.Element; import androidx.renderscript.RenderScript; import androidx.renderscript.ScriptIntrinsicBlur; public class BlurUtils { // 生成模糊后的Bitmap public static Bitmap createBlurBitmap(Context context, View view, float blurRadius) { Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); view.draw(canvas); RenderScript rs = RenderScript.create(context); ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); Allocation input = Allocation.createFromBitmap(rs, bitmap); Allocation output = Allocation.createTyped(rs, input.getType()); blurScript.setRadius(blurRadius); blurScript.setInput(input); blurScript.forEach(output); output.copyTo(bitmap); rs.destroy(); return bitmap; } }
步骤3:修改Pop类的代码
import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.os.Build; import android.os.Bundle; import android.util.DisplayMetrics; import android.view.View; import android.view.WindowManager; import androidx.appcompat.app.AppCompatActivity; public class Pop extends AppCompatActivity { // 建议改成AppCompatActivity,兼容性更好 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 获取当前屏幕的根视图,用于生成模糊背景 View rootView = getWindow().getDecorView().getRootView(); rootView.setDrawingCacheEnabled(true); Bitmap blurredBitmap = BlurUtils.createBlurBitmap(this, rootView, 20f); // 设置弹窗背景为模糊后的图片 getWindow().setBackgroundDrawable(new BitmapDrawable(getResources(), blurredBitmap)); setContentView(R.layout.popup); // 背景变暗效果(可选,增强模糊的层次感) getWindow().getAttributes().dimAmount = 0.4f; getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); int width = dm.widthPixels; int height = dm.heightPixels; getWindow().setLayout((int)(width*.8),(int)(height*.6)); // 释放缓存 rootView.setDrawingCacheEnabled(false); } }
方案三:第三方库(新手友好,适配全版本)
如果不想自己写复杂的模糊逻辑,推荐使用成熟的第三方库BlurView,它已经封装好了所有适配细节:
步骤1:添加依赖
在app/build.gradle中添加依赖(请替换为最新版本):
implementation 'com.github.Dimezis:BlurView:3.7.0'
步骤2:修改弹窗布局popup.xml
把原来的LinearLayout改成FrameLayout,嵌套BlurView作为背景:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center"> <!-- 模糊背景层 --> <eightbitlab.com.blurview.BlurView android:id="@+id/blurView" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- 这里放你原来的弹窗内容 --> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp" android:background="@android:color/white" <!-- 可选:给内容层加白色背景,增强可读性 --> android:layout_margin="16dp"> <!-- 你的弹窗内容,比如TextView、Button等 --> </LinearLayout> </eightbitlab.com.blurview.BlurView> </FrameLayout>
步骤3:初始化BlurView
在Pop类的onCreate方法中添加初始化代码:
import android.os.Bundle; import android.util.DisplayMetrics; import android.view.View; import android.view.ViewGroup; import android.view.Window; import eightbitlab.com.blurview.BlurAlgorithm; import eightbitlab.com.blurview.BlurView; import eightbitlab.com.blurview.RenderScriptBlur; import androidx.appcompat.app.AppCompatActivity; public class Pop extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.popup); BlurView blurView = findViewById(R.id.blurView); float blurRadius = 20f; // 模糊半径 // 设置模糊的背景来源 Window window = getWindow(); View decorView = window.getDecorView(); ViewGroup rootView = (ViewGroup) decorView.findViewById(android.R.id.content); window.setBackgroundDrawable(null); blurView.setupWith(rootView) .setFrameClearDrawable(decorView.getBackground()) .setBlurAlgorithm(new RenderScriptBlur(this)) // 使用RenderScript实现模糊 .setBlurRadius(blurRadius) .setBlurAutoUpdate(true) // 自动更新模糊效果 .setHasFixedTransformationMatrix(true); DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); int width = dm.widthPixels; int height = dm.heightPixels; getWindow().setLayout((int)(width*.8),(int)(height*.6)); } }
以上三种方案,新手最推荐用第三种,因为第三方库已经处理了所有版本适配和细节问题,只需要简单配置就能实现完美的模糊效果~
内容的提问来源于stack exchange,提问作者user3024958
相关产品推荐
相关产品推荐

