Создание размытого прозрачного фонового эффекта

Я пытаюсь сделать представление, которое будет иметь фон, который не только прозрачен, но также будет иметь эффект размытия. Таким образом, взгляды внизу выглядят не в фокусе. Я хочу, чтобы он выглядел так, как будто экран удерживает кнопку питания. Любые идеи?

Ответ 1

Теперь, когда флаг окна устарел, вы должны размыть себя. Я ответил на это в другом месте, но вот как вы можете размыть взгляд:

Теперь вы можете использовать ScriptIntrinsicBlur из библиотеки RenderScript для быстрого размытия. Здесь описано, как получить доступ к API RenderScript. Следующим является класс, который я сделал для размытия представлений и растровых изображений:

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

Чтобы применить это к фрагменту, добавьте следующее в 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));
        }
    });
}

ПРИМЕЧАНИЕ. Для этого решения требуется min sdk API 17

РЕДАКТИРОВАТЬ: Renderscript включен в поддержку v8, позволяя этому ответу перейти на api 8. Чтобы включить его с помощью gradle, включите эти строки в ваш файл gradle из этого answer) и используйте Renderscript из пакета android.support.v8.renderscript:

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

Ответ 2

Если все, что вы хотите сделать, это размыть фон окна за вашей активностью, вы можете использовать этот вызов из своей активности (или любого класса, например, AlertDialog, который имеет окно).

getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);

Обновление: этот флаг устарел в Android 4.0 и больше не работает.

Ответ 3

Blurry - отличный вариант, который легко даст вам эффект, который вы ищете: https://github.com/wasabeef/Blurry

после добавления его в проект, оберните вид, который вы хотите размыть в FrameLayout, затем используйте эту строку, когда хотите размыть:

Blurry.with(this).radius(25).sampling(2).onto((ViewGroup) findViewById(R.id.viewToBlurWrapper));