android 实现弹窗背景模糊

该文章介绍了如何在Android应用中为对话框添加模糊背景效果,包括在XML布局中添加FrameLayout,设置透明背景,使用工具类进行屏幕截图、高斯模糊处理以及实现淡入淡出动画。通过RenderScript进行图片模糊处理,同时提供了处理背景隐藏的代码示例。

先看效果:

有点糊,不过效果还是能看到的。

步骤:

1:在你的界面布局最下面加入这个(哪个界面要弹窗就在哪个界面xml加)

<!-- 这里的FrameLayout用于承载对话框的背景 -->
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/iv_dialog_bg"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</FrameLayout>

2:添加透明背景

<item name="android:windowTranslucentStatus">true</item>

如图:

3:工具类先贴出来吧,主要代码都抽到工具类了


/**
 * @Description: java类作用描述
 * @author: 小张
 * @date: 2023/2/10
 */
public class BlurryBgUtil {
    private static int originalW;
    private static int originalH;

    private static Bitmap captureScreen(Activity activity) {
        activity.getWindow().getDecorView().destroyDrawingCache();  //先清理屏幕绘制缓存(重要)
        activity.getWindow().getDecorView().setDrawingCacheEnabled(true);
        Bitmap bmp = activity.getWindow().getDecorView().getDrawingCache();
        //获取原图尺寸
        originalW = bmp.getWidth()+10;
        originalH = bmp.getHeight();
        //对原图进行缩小,提高下一步高斯模糊的效率
        bmp = Bitmap.createScaledBitmap(bmp, originalW / 2, originalH / 2, false);
        return bmp;
    }

    public static void setScreenBgLight(Activity context) {
        Window window = context.getWindow();
        WindowManager.LayoutParams lp;
        if (window != null) {
            lp = window.getAttributes();
            lp.dimAmount = 0.1f;
            window.setAttributes(lp);
        }
    }

    public static void handleBlur(Activity context, ImageView dialogBg,Handler mHandler) {
        Bitmap bp = captureScreen(context);
        bp = blur(bp,context);                      //对屏幕截图模糊处理
        //将模糊处理后的图恢复到原图尺寸并显示出来
        bp = Bitmap.createScaledBitmap(bp, originalW, originalH, false);
        dialogBg.setImageBitmap(bp);
        dialogBg.setVisibility(View.VISIBLE);
        //防止UI线程阻塞,在子线程中让背景实现淡入效果
        asyncRefresh(true,dialogBg,mHandler);
    }
    public static void asyncRefresh(boolean in,ImageView dialogBg,Handler mHandler) {
        //淡出淡入效果的实现
        if(in) {    //淡入效果
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 256; i += 5) {
                        refreshUI(i,dialogBg);//在UI线程刷新视图
                        try {
                            Thread.sleep(4);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        } else {    //淡出效果
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 255; i >= 0; i -= 5) {
                        refreshUI(i,dialogBg);//在UI线程刷新视图
                        try {
                            Thread.sleep(4);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    //当淡出效果完毕后发送消息给mHandler把对话框背景设为不可见
                    mHandler.sendEmptyMessage(0);
                }
            }).start();
        }
    }

    public static void refreshUI(final int i, ImageView dialogBg) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                dialogBg.setImageAlpha(i);
            }
        });
    }

    public static void hideBlur(ImageView dialogBg,Handler mHandler) {
        //把对话框背景隐藏
        asyncRefresh(false,dialogBg,mHandler);
        System.gc();
    }

    public static Bitmap blur(Bitmap bitmap,Activity activity) {
        //使用RenderScript对图片进行高斯模糊处理
        Bitmap output = Bitmap.createBitmap(bitmap); // 创建输出图片
        RenderScript rs = RenderScript.create(activity); // 构建一个RenderScript对象
        ScriptIntrinsicBlur gaussianBlue = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); //
        // 创建高斯模糊脚本
        Allocation allIn = Allocation.createFromBitmap(rs, bitmap); // 开辟输入内存
        Allocation allOut = Allocation.createFromBitmap(rs, output); // 开辟输出内存
        float radius = 10f;     //设置模糊半径
        gaussianBlue.setRadius(radius); // 设置模糊半径,范围0f<radius<=25f
        gaussianBlue.setInput(allIn); // 设置输入内存
        gaussianBlue.forEach(allOut); // 模糊编码,并将内存填入输出内存
        allOut.copyTo(output); // 将输出内存编码为Bitmap,图片大小必须注意
        rs.destroy();
        //rs.releaseAllContexts(); // 关闭RenderScript对象,API>=23则使用rs.releaseAllContexts()
        return output;
    }
}

 

4:在需要弹窗的界面中:initView中

private ImageView dialogBg;
private Handler mHandler;


*****


之后获取 刚刚布局里的哪个imageview 
//模糊背景
dialogBg = findViewById(R.id.iv_dialog_bg);

//创建activity先把对话框背景图设为不可见
dialogBg.setImageAlpha(0);
dialogBg.setVisibility(View.GONE);

//hanlder初始化
mHandler = new Handler() {

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        if (msg.what == 0) {
            dialogBg.setVisibility(View.GONE);
        }
    }
};

5:点击弹窗触发时:

然后在点击弹窗触发的时候:
BlurryBgUtil.handleBlur(Linkman_Activity.this,dialogBg,mHandler);

如图:

6:popup点击取消 确认触发

// 背景淡出
                BlurryBgUtil.hideBlur(dialogBg,mHandler);

如图:

7:shift + F10 (运行)

完活。就这么多

又是被美工逼着进步的一天啊~~~. 

### Android 对话框背景自定义 在 Android 中,可以通过多种方式实现对话框 (Dialog) 的背景定制化。以下是几种常见的方法: #### 方法一:通过 `setCanceledOnTouchOutside` 和 `Window setBackgroundDrawableResource` 可以创建一个透明的布局作为背景,并将其应用到 Dialog 上。 ```java AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setView(R.layout.custom_dialog); // 创建并显示对话框 final AlertDialog dialog = builder.create(); dialog.show(); // 设置背景颜色或图片 if (dialog.getWindow() != null) { dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent); // 自定义背景为透明[^1] } ``` 这种方法适用于希望完全移除默认灰色背景或者替换为其他资源的情况。 --- #### 方法二:使用 `DialogFragment` 并设置模糊效果 如果需要更复杂的视觉效果(如模糊),可以在后台添加一层带有高斯模糊处理的效果层。这通常涉及使用第三方库来简化操作过程。 例如,借助 [BlurView](https://github.com/Dimezis/BlurView),能够轻松实现毛玻璃风格的背景。 ```xml <!-- res/layout/dialog_fragment.xml --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <!-- 添加 BlurView 或者其他视图组件 --> </FrameLayout> ``` 接着,在 Java/Kotlin 文件里初始化该 Fragment 及其样式属性。 ```java public class CustomDialogFragment extends DialogFragment { @Override public void onStart() { super.onStart(); if (getDialog() != null && getDialog().getWindow() != null){ getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); // 应用模糊逻辑或其他特效... } } @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.dialog_fragment, container, false); } } ``` 上述代码片段展示了如何利用 `DialogFragment` 来构建更加灵活可控的内容区域。 --- #### 方法三:调整按钮文字颜色及其他细节优化 除了改变整体外观外,还可以单独修改某些 UI 部件的颜色参数,比如确认取消键上的字体色调等。 ```java AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setMessage("Sample Message"); // 定义正负向动作监听器以及对应的文字描述 builder.setPositiveButton("OK", ... ); builder.setNegativeButton("Cancel", ... ); // 获取内部控件实例进而施加个性化设定 AlertDialog alert = builder.create(); alert.setOnShowListener(dialogInterface -> { Button positiveButton = alert.getButton(AlertDialog.BUTTON_POSITIVE); Button negativeButton = alert.getButton(AlertDialog.BUTTON_NEGATIVE); if (positiveButton != null) { positiveButton.setTextColor(ContextCompat.getColor(context, R.color.your_custom_color)); // 更改颜色[^2] } }); ``` 此部分重点在于获取原始对象之后再做进一步装饰工作。 --- #### 使用适配器增强列表型数据展示能力 当涉及到复杂的数据集合呈现需求时,则可能需要用到专门设计过的 Adapter 类型解决方案。这里推荐一款非常强大的工具——[BaseRecyclerViewAdapterHelper](https://github.com/CymChad/BaseRecyclerViewAdapterHelper)[^3] ,它极大地降低了开发难度的同时还提供了丰富的扩展选项满足各类场景下的差异化表现形式要求。 综上所述,无论是简单的全局主题切换还是精细至每一个独立单元格级别的控制都可以找到合适的途径达成目标!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值