天天看點

android 實作彈窗背景模糊

先看效果:

android 實作彈窗背景模糊
android 實作彈窗背景模糊

有點糊,不過效果還是能看到的。

步驟:

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>
           

如圖:

android 實作彈窗背景模糊

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);
           

如圖:

android 實作彈窗背景模糊

6:popup點選取消 确認觸發

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

如圖:

android 實作彈窗背景模糊

7:shift + F10 (運作)

完活。就這麼多

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