Create blurry transparent background effect

Now that the window flag is deprecated, you’ve got to blur yourself. I answered this elsewhere but here is how you can blur a view:

You can now use ScriptIntrinsicBlur from the RenderScript library to blur quickly. Here is how to access the RenderScript API. The following is a class I made to blur Views and Bitmaps:

import android.support.v8.renderscript.*;

public class BlurBuilder {
    private static final float BITMAP_SCALE = 0.4f;
    private static final float BLUR_RADIUS = 7.5f;

    public static Bitmap blur(View v) {
        return blur(v.getContext(), getScreenshot(v));
    }

    public static Bitmap blur(Context ctx, Bitmap image) {
        int width = Math.round(image.getWidth() * BITMAP_SCALE);
        int height = Math.round(image.getHeight() * BITMAP_SCALE);

        Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false);
        Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);

        RenderScript rs = RenderScript.create(ctx);
        ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
        Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);
        theIntrinsic.setRadius(BLUR_RADIUS);
        theIntrinsic.setInput(tmpIn);
        theIntrinsic.forEach(tmpOut);
        tmpOut.copyTo(outputBitmap);

        return outputBitmap;
    }

    private static Bitmap getScreenshot(View v) {
        Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(b);
        v.draw(c);
        return b;
    }
}

To apply this to a fragment, add the following to onCreateView:

final Activity activity = getActivity();
final View content = activity.findViewById(android.R.id.content).getRootView();
if (content.getWidth() > 0) {
    Bitmap image = BlurBuilder.blur(content);
    window.setBackgroundDrawable(new BitmapDrawable(activity.getResources(), image));
} else {
    content.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            Bitmap image = BlurBuilder.blur(content);
            window.setBackgroundDrawable(new BitmapDrawable(activity.getResources(), image));
        }
    });
}

NOTE: This solution requires min sdk to be API 17

EDIT: Renderscript is included into support v8 enabling this answer down to api 8. To enable it using gradle include these lines into your gradle file (from this answer) and use Renderscript from package android.support.v8.renderscript:

android {
  ...
  defaultConfig {
    ...
    renderscriptTargetApi *your target api*
    renderscriptSupportModeEnabled true
  }
  ...
}

Leave a Comment