Создать прозрачный фон размытым эффектом


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

3 68

3 ответа:

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

теперь вы можете использовать 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

EDIT: Renderscript включен в поддержку v8, позволяя этот ответ вплоть до api 8. Чтобы включить его с помощью ш включите эти строки в свой файл gradle (из этого ответ) и использовать Renderscript из пакета android.поддержка.v8.решение RenderScript:

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

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

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

обновление: этот флаг поддерживается в Android 4.0 и больше не работает.

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

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

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