当前位置: 首页 > 知识库问答 >
问题:

AlertDialog与位置中心的模糊背景

解念
2023-03-14

问题

试图模糊(而不是变暗)对话框的背景。

并且FLAG_BLUR_BEHIND不建议使用。

方法是,从当前视图中截图并模糊它。然后,当出现AlertDialog时,将其附加到背景,然后它就会工作。

但是AlertDialog总是在顶部而不是中间。(查看图片)

WindowManager。LayoutParams在附加后无效。(在将其附加到背景之前,警报可以定位到中心位置,但在将模糊视图附加到背景之后,警报对话框始终转到顶部)

如何在屏幕中设置警报中心?

以下是我尝试过的代码,任何指南都将不胜感激,

当我按back时显示警报。

     @Override
        public void onBackPressed() {

            AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this, R.style.AlertDialogCustom);
            builder.setTitle("Lets Blur");
            builder.setMessage("This is Blur Demo");
            builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });


            dialog = builder.create();

// this position alert in the CENTER
            dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
            WindowManager.LayoutParams wmlp = dialog.getWindow().getAttributes();
            wmlp.gravity = Gravity.CENTER;
            dialog.show();

            new BlurAsyncTask().execute();

        }

        class BlurAsyncTask extends AsyncTask<Void, Integer, Bitmap> {


            protected Bitmap doInBackground(Void...arg0) {

                Bitmap map  = AppUtils.takeScreenShot(MainActivity.this);
                Bitmap fast = new BlurView().fastBlur(map, 10);
                return fast;
            }


            protected void onPostExecute(Bitmap result) {
                if (result != null){
                    final Drawable draw=new BitmapDrawable(getResources(),result);
                    Window window = dialog.getWindow();
// this position alert again in the TOP -- need to avoid that!
                    window.setBackgroundDrawable(draw);
                    window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
                    window.setGravity(Gravity.CENTER);
                    dialog.show();

                }

            }

其他类别

应用

public class AppUtils {

    public static Bitmap takeScreenShot(Activity activity) {
        View view = activity.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();


        Bitmap b1 = view.getDrawingCache();
        Rect frame = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
        int statusBarHeight = frame.top;

        Display display = activity.getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        int width = size.x;
        int height = size.y;


        Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height - statusBarHeight);
        view.destroyDrawingCache();
        return b;
    }
}

模糊视图

public class BlurView {

    public Bitmap fastBlur(Bitmap sentBitmap, int radius) {
        Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
        if (radius < 1) {
            return (null);
        }
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        int[] pix = new int[w * h];
        Log.e("pix", w + " " + h + " " + pix.length);
        bitmap.getPixels(pix, 0, w, 0, 0, w, h);
        int wm = w - 1;
        int hm = h - 1;
        int wh = w * h;
        int div = radius + radius + 1;
        int r[] = new int[wh];
        int g[] = new int[wh];
        int b[] = new int[wh];
        int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
        int vmin[] = new int[Math.max(w, h)];
        int divsum = (div + 1) >> 1;
        divsum *= divsum;
        int dv[] = new int[256 * divsum];
        for (i = 0; i < 256 * divsum; i++) {
            dv[i] = (i / divsum);
        }
        yw = yi = 0;
        int[][] stack = new int[div][3];
        int stackpointer;
        int stackstart;
        int[] sir;
        int rbs;
        int r1 = radius + 1;
        int routsum, goutsum, boutsum;
        int rinsum, ginsum, binsum;
        for (y = 0; y < h; y++) {
            rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
            for (i = -radius; i <= radius; i++) {
                p = pix[yi + Math.min(wm, Math.max(i, 0))];
                sir = stack[i + radius];
                sir[0] = (p & 0xff0000) >> 16;
                sir[1] = (p & 0x00ff00) >> 8;
                sir[2] = (p & 0x0000ff);
                rbs = r1 - Math.abs(i);
                rsum += sir[0] * rbs;
                gsum += sir[1] * rbs;
                bsum += sir[2] * rbs;
                if (i > 0) {
                    rinsum += sir[0];
                    ginsum += sir[1];
                    binsum += sir[2];
                } else {
                    routsum += sir[0];
                    goutsum += sir[1];
                    boutsum += sir[2];
                }
            }
            stackpointer = radius;
            for (x = 0; x < w; x++) {
                r[yi] = dv[rsum];
                g[yi] = dv[gsum];
                b[yi] = dv[bsum];
                rsum -= routsum;
                gsum -= goutsum;
                bsum -= boutsum;
                stackstart = stackpointer - radius + div;
                sir = stack[stackstart % div];
                routsum -= sir[0];
                goutsum -= sir[1];
                boutsum -= sir[2];
                if (y == 0) {
                    vmin[x] = Math.min(x + radius + 1, wm);
                }
                p = pix[yw + vmin[x]];
                sir[0] = (p & 0xff0000) >> 16;
                sir[1] = (p & 0x00ff00) >> 8;
                sir[2] = (p & 0x0000ff);
                rinsum += sir[0];
                ginsum += sir[1];
                binsum += sir[2];
                rsum += rinsum;
                gsum += ginsum;
                bsum += binsum;
                stackpointer = (stackpointer + 1) % div;
                sir = stack[(stackpointer) % div];
                routsum += sir[0];
                goutsum += sir[1];
                boutsum += sir[2];
                rinsum -= sir[0];
                ginsum -= sir[1];
                binsum -= sir[2];
                yi++;
            }
            yw += w;
        }
        for (x = 0; x < w; x++) {
            rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
            yp = -radius * w;
            for (i = -radius; i <= radius; i++) {
                yi = Math.max(0, yp) + x;
                sir = stack[i + radius];
                sir[0] = r[yi];
                sir[1] = g[yi];
                sir[2] = b[yi];
                rbs = r1 - Math.abs(i);
                rsum += r[yi] * rbs;
                gsum += g[yi] * rbs;
                bsum += b[yi] * rbs;
                if (i > 0) {
                    rinsum += sir[0];
                    ginsum += sir[1];
                    binsum += sir[2];
                } else {
                    routsum += sir[0];
                    goutsum += sir[1];
                    boutsum += sir[2];
                }
                if (i < hm) {
                    yp += w;
                }
            }
            yi = x;
            stackpointer = radius;
            for (y = 0; y < h; y++) {
                // Preserve alpha channel: ( 0xff000000 & pix[yi] )
                pix[yi] = ( 0xff000000 & pix[yi] ) | ( dv[rsum] << 16 ) | ( dv[gsum] << 8 ) | dv[bsum];
                rsum -= routsum;
                gsum -= goutsum;
                bsum -= boutsum;
                stackstart = stackpointer - radius + div;
                sir = stack[stackstart % div];
                routsum -= sir[0];
                goutsum -= sir[1];
                boutsum -= sir[2];
                if (x == 0) {
                    vmin[y] = Math.min(y + r1, hm) * w;
                }
                p = x + vmin[y];
                sir[0] = r[p];
                sir[1] = g[p];
                sir[2] = b[p];
                rinsum += sir[0];
                ginsum += sir[1];
                binsum += sir[2];
                rsum += rinsum;
                gsum += ginsum;
                bsum += binsum;
                stackpointer = (stackpointer + 1) % div;
                sir = stack[stackpointer];
                routsum += sir[0];
                goutsum += sir[1];
                boutsum += sir[2];
                rinsum -= sir[0];
                ginsum -= sir[1];
                binsum -= sir[2];
                yi += w;
            }
        }
        Log.e("pix", w + " " + h + " " + pix.length);
        bitmap.setPixels(pix, 0, w, 0, 0, w, h);
        return (bitmap);
    }
}

编辑:答案的概念

  1. 拍摄屏幕截图
  2. 以编程方式为屏幕快照设置动画/模糊/任何效果
  3. 使用没有任何内容的对话框获取Current窗口
  4. 附加具有效果的屏幕截图
  5. 显示我想要显示的真实视图

附带说明:这可以用来附加任何类型的背景!模糊...暗淡...明亮...只需添加接受位图的正确方法,并在BlurView类中返回带有所需更改的位图。我添加了一个模糊的。

共有1个答案

柴嘉年
2023-03-14

注意:这个屏幕背景可以是你在它上面的任何东西,它所做的就是截取它的屏幕截图并模糊,最终将其设置为具有模糊效果的alertDialog的背景

问题是带有模糊背景的alertDialog始终位于顶部,我无法更改。

我想出了这个解决方案。

我不得不使用两个alertDialogs一个用于模糊效果(用于getWindow()),但现在无法显示(我删除了它的setContentView/可以使用透明背景)

另一个是模糊效果后显示的真实警报对话框。

主要活动

public class MainActivity extends AppCompatActivity {

    private  AlertDialog dialogWhichDisplayAlert;
    private  Dialog fakeDialogUseToGetWindowForBlurEffect;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


    }


    @Override
    public void onBackPressed() {


        fakeDialogUseToGetWindowForBlurEffect = new Dialog(MainActivity.this);
        //  fakeDialogUseToGetWindowForBlurEffect.setContentView(R.layout.fakealert); // removed the content so not visible



        new BlurAsyncTask().execute();

    }

    class BlurAsyncTask extends AsyncTask<Void, Integer, Bitmap> {


        protected Bitmap doInBackground(Void...arg0) {

            Bitmap map  = AppUtils.takeScreenShot(MainActivity.this);
            Bitmap fast = new BlurView().fastBlur(map, 10);
            return fast;
        }


        protected void onPostExecute(Bitmap result) {
            if (result != null){
                final Drawable draw=new BitmapDrawable(getResources(),result);
                Window window = fakeDialogUseToGetWindowForBlurEffect.getWindow();
                window.setBackgroundDrawable(draw);
                window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
                window.setGravity(Gravity.CENTER);
                fakeDialogUseToGetWindowForBlurEffect.show();


                // real one
                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this, R.style.AlertDialogCustom);
                builder.setTitle("Lets Blur");
                builder.setMessage("This is Blur Demo");
                builder.setCancelable(false);
                builder.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        fakeDialogUseToGetWindowForBlurEffect.dismiss();
                        dialog.cancel();
                    }
                });
                builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        fakeDialogUseToGetWindowForBlurEffect.dismiss();
                        dialog.cancel();
                    }
                });
                dialogWhichDisplayAlert = builder.create();

                // position real dialogWhichDisplayAlert using Gravity.CENTER;
                dialogWhichDisplayAlert.requestWindowFeature(Window.FEATURE_NO_TITLE);
                WindowManager.LayoutParams wmlp = dialogWhichDisplayAlert.getWindow().getAttributes();
                wmlp.gravity = Gravity.CENTER;
                dialogWhichDisplayAlert.show();

            }

        }
    }
}

[使用的其他类别与问题相同]

风格

<style name="AlertDialogCustom" parent="@android:style/Theme.Dialog">
        <item name="android:textColor">#00FF00</item>
        <item name="android:typeface">monospace</item>
        <item name="android:textSize">10sp</item>
    </style>

发出

 类似资料:
  • 我想将黑色透明背景更改为白色透明,试图在样式中更改它,但它不起作用。 我还想将黑色模糊背景更改为白色模糊,尝试在样式中更改它。 我也尝试了这里提到的渲染脚本、快速模糊、xml,但它只改变了对话框的白色背景 有什么办法可以改变吗?提前谢谢!

  • 我试图在AlertDialog后面有一个模糊的背景。该过程如下所示:拍摄活动的屏幕截图并将其模糊,然后将其保存到位图中。然后将此位图转换为可绘制位图。然后,我使用这行代码

  • 问题内容: 我希望网站上的弹出窗口具有 Vista/7航空玻璃风格的效果,并且它必须是动态的。我很好这不是一个跨浏览器的效果,只要该网站仍然 _适用_于所有现代浏览器。 我的第一次尝试是使用类似 但是,正如我应该预期的那样, 这导致 对话框的 内容 模糊并且背景保持清晰。 有什么方法可以使用CSS来模糊半透明元素的背景而不是其内容? 问题答案: 由于除FF以外,其他浏览器似乎未广泛支持该属性,因此

  • 主要内容:示例中位数模糊操作类似于其他平均方法。 这里,图像的中心元素被内核区域中所有像素的中值所代替。该操作在消除噪音的同时处理边缘。 可以使用类的方法在图像上执行此操作。 以下是这种方法的语法 - 该方法接受以下参数 - src - 表示此操作的源(输入图像)的对象。 dst - 表示此操作的目标(输出图像)的对象。 ksize - 表示内核大小的对象。 示例 以下程序演示如何对图像执行中位模糊操作。 假定

  • 我想用透明的背景显示警报对话框。我的警报对话框代码为: 我的背景图像包含圆形的角,但不幸的是,流行是以矩形白色背景出现的。任何身体plz建议我的想法。提前谢谢。

  • 我希望对话框下有模糊的屏幕,所以我拍摄活动的“截图”,模糊它,并将其设置为可位图绘制的对话框窗口背景。奇怪的是对话框不再集中在屏幕上,即使调用了setCanceledOnTouchOutside(true),触摸外部对话框也不会关闭它。 问题是:为什么这不起作用?分别如何创建背景模糊的对话框?