Создать размытый прозрачный фоновый эффект - PullRequest
68 голосов
/ 23 июля 2011

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

Ответы [ 3 ]

128 голосов
/ 10 января 2014

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

Теперь вы можете использовать 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 включен в support v8, позволяя получить этот ответ вплоть до api 8. Чтобы включить егоиспользуя gradle включите эти строки в свой файл gradle (из этого ответа ) и используйте Renderscript из пакета android.support.v8.renderscript :

android {
  ...
  defaultConfig {
    ...
    renderscriptTargetApi *your target api*
    renderscriptSupportModeEnabled true
  }
  ...
}
16 голосов
/ 23 июля 2011

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

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

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

0 голосов
/ 19 сентября 2017

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

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

Blurry.with(this).radius(25).sampling(2).onto((ViewGroup) findViewById(R.id.viewToBlurWrapper));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...