android - Desenfoque de fondo detrás de AlertDialog
android-alertdialog blur (4)
Así es como he hecho fondo de mi cuadro de diálogo borroso
Pasos
1) Tome la instantánea de su fondo utilizando el código de abajo
private 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;
int width = activity.getWindowManager().getDefaultDisplay().getWidth();
int height = activity.getWindowManager().getDefaultDisplay().getHeight();
Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height - statusBarHeight);
view.destroyDrawingCache();
return b;
}
utilícelo Like This Bitmap map=takeScreenShot(BlurImageView.this);
// Tu nombre de actividad
2) Llame al método Bitmap fast=fastblur(map, 10);
Lo tengo de Here
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);
}
3) Finalmente al hacer clic en el Button
btnblur.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder builder=new AlertDialog.Builder(BlurImageView.this,R.style.Theme_D1NoTitleDim);
builder.setTitle("Content");
builder.setMessage("CLICK OK to Exit");
builder.setPositiveButton("ON", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
back_dim_layout.setVisibility(View.GONE);
dialog.cancel();
}
});
alert=builder.create();
Bitmap map=takeScreenShot(BlurImageView.this);
Bitmap fast=fastblur(map, 10);
final Drawable draw=new BitmapDrawable(getResources(),fast);
alert.getWindow().setBackgroundDrawable(draw);
alert.show();
}
});
Eso es todo ahora. Puedes ver la imagen borrosa detrás de ti.
Espero que esto pueda ayudar por completo para AnyOne ...
Como sabemos por API 14, el Blur de abajo ha sido desaprobado.
dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
¿Hay alguna alternativa para que esto haga que el Desenfoque de la pantalla detrás del diálogo He intentado el desenfoque RÁPIDO
Esta solución de nitesh funciona como a continuación
Pero si no puede hacer que su alerta al centro (como a mí) también verifique mi respuesta, que está Here
Lo que hice fue
usé dos alertDialogs
uno para el efecto de desenfoque (para el uso de getWindow()
) y no se muestra ahora ( setContentView
su setContentView
/ puedo usar un fondo transparente)
El otro es el verdadero alertDialog
conseguido después del efecto borroso.
Fuera puesto
Inténtalo de esta manera, te ayudaré.
crear un styles.xml
<style name="Theme.D1NoTitleDim" parent="android:style/Theme.Translucent">
<item name="android:windowNoTitle">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:background">@android:color/transparent</item>
</style>
Y luego en tu dialogo
dialog = new Dialog(context,styles);
Esto esta funcionando bien para mi
Para más te sugiero que veas este Example
Para que un desenfoque rápido y para resolver el problema del diálogo aparezca en la parte superior de la pantalla, creo que hay una solución más fácil:
// Custom Dialog to be called in the Activity choosed.
public class CustomDialog {
private Dialog dialog;
public CustomDialog(AppCompatActivity activity) {
dialog = new Dialog(activity);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
View viewCustomDialog = LayoutInflater.from(activity).inflate(R.layout.custom_dialog, null);
dialog.setContentView(viewCustomDialog);
RelativeLayout rootView = viewCustomDialog.findViewById(R.id.rootView);
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
layoutParams.gravity = Gravity.CENTER;
dialog.getWindow().setAttributes(layoutParams);
// First get bitmap with blur filter applied, using the function blur presented here,
// or another function.
// Activity parameter is the Activity for which you call dialog.show();
Bitmap bitmap = Utils.blur(activity);
// Get bitmap height.
int bitmapHeight = bitmap.getHeight();
dialog.setOnShowListener(dialogInterface -> {
// When dialog is shown, before set new blurred image for background drawable,
// the root view height and dialog margin are saved.
int rootViewHeight = rootView.getHeight();
int marginLeftAndRight = dialog.getWindow().getDecorView().getPaddingLeft();
// Set new blurred image for background drawable.
dialog.getWindow().setBackgroundDrawable(new BitmapDrawable(builder.context.getResources(), bitmap));
// After get positions and heights, recover and rebuild original marginTop position,
// that is (bitmapHeight - rootViewHeight) / 2.
// Also recover and rebuild Dialog original left and right margin.
FrameLayout.LayoutParams rootViewLayoutParams = (FrameLayout.LayoutParams)rootView.getLayoutParams();
rootViewLayoutParams.setMargins(marginLeftAndRight, (bitmapHeight - rootViewHeight) / 2, marginLeftRight, 0);
});
dialog.show();
}
}
Método de desenfoque:
public static Bitmap blur(AppCompatActivity activity) {
Bitmap bitmap = Utils.takeScreenShot(activity);
RenderScript renderScript = RenderScript.create(activity);
// This will blur the bitmapOriginal with a radius of 16 and save it in bitmapOriginal
final Allocation input = Allocation.createFromBitmap(renderScript, bitmap); // Use this constructor for best performance, because it uses USAGE_SHARED mode which reuses memory
final Allocation output = Allocation.createTyped(renderScript, input.getType());
final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript));
script.setRadius(16f);
script.setInput(input);
script.forEach(output);
output.copyTo(bitmap);
return bitmap;
}
Método TakeScreenShot:
public static Bitmap takeScreenShot(AppCompatActivity activity) {
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bitmap = view.getDrawingCache();
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
int[] widthHeight = getScreenSize(activity);
Bitmap bitmapResult = Bitmap.createBitmap(bitmap, 0, statusBarHeight, widthHeight[0], widthHeight[1] - statusBarHeight);
view.destroyDrawingCache();
return bitmapResult;
}
Método GetScreenSize:
public static int[] getScreenSize(Context context) {
int[] widthHeight = new int[2];
widthHeight[WIDTH_INDEX] = 0;
widthHeight[HEIGHT_INDEX] = 0;
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
widthHeight[WIDTH_INDEX] = size.x;
widthHeight[HEIGHT_INDEX] = size.y;
if (!isScreenSizeRetrieved(widthHeight)) {
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
widthHeight[0] = metrics.widthPixels;
widthHeight[1] = metrics.heightPixels;
}
if (!isScreenSizeRetrieved(widthHeight)) {
widthHeight[0] = display.getWidth(); // deprecated
widthHeight[1] = display.getHeight(); // deprecated
}
return widthHeight;
}
private static boolean isScreenSizeRetrieved(int[] widthHeight) {
return widthHeight[WIDTH_INDEX] != 0 && widthHeight[HEIGHT_INDEX] != 0;
}
Y para usar RenderScript (para desenfocar), en el build.gradle de la aplicación debe agregar:
defaultConfig {
...
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
}