Erstellen Sie einen verschwommenen transparenten Hintergrundeffekt

70

Ich versuche, eine Ansicht zu erstellen, die einen Hintergrund hat, der nicht nur transparent ist, sondern auch einen Unschärfeeffekt hat. Auf diese Weise scheinen die Ansichten darunter unscharf zu sein. Ich möchte, dass es so aussieht wie der Bildschirm, nachdem Sie den Netzschalter gedrückt haben. Irgendwelche Ideen?

b_yng
quelle

Antworten:

138

Jetzt, da die Fensterflagge veraltet ist, müssen Sie sich selbst verwischen. Ich habe dies an anderer Stelle beantwortet, aber hier ist, wie Sie eine Ansicht verwischen können:

Sie können jetzt ScriptIntrinsicBlur aus der RenderScript-Bibliothek verwenden, um schnell zu verwischen. So greifen Sie auf die RenderScript-API zu. Das Folgende ist eine Klasse, die ich erstellt habe, um Ansichten und Bitmaps zu verwischen:

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

Fügen Sie Folgendes hinzu, um dies auf ein Fragment anzuwenden 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));
        }
    });
}

HINWEIS: Für diese Lösung muss min sdk API 17 sein

BEARBEITEN : Renderscript ist in Support v8 enthalten und ermöglicht diese Antwort bis auf API 8. Um es mit Gradle zu aktivieren, fügen Sie diese Zeilen in Ihre Gradle-Datei ein (aus dieser Antwort ) und verwenden Sie Renderscript aus dem Paket android.support.v8.renderscript :

android {
  ...
  defaultConfig {
    ...
    renderscriptTargetApi *your target api*
    renderscriptSupportModeEnabled true
  }
  ...
}
b_yng
quelle
1
Du rockst. Das hat mir sehr geholfen. Eine Sache, die ich hinzugefügt habe, ist, dass die von der Unschärfefunktion zurückgegebene Bitmap eine TransitionDrawable ist. Dies trägt dazu bei, dass der Unschärfeeffekt flüssiger erscheint.
Jessie A. Morris
1
Möchten Sie kommentieren, wie die Konstanten BITMAP_SCALE und BLUR_RADIUS funktionieren? Vielen Dank
hitch.united
2
Das funktioniert bei mir nicht. Der Hintergrund ist überhaupt nicht unscharf
Thomas Teilmann
1
Für diejenigen, die sagen, dass es nicht funktioniert ... haben Sie versucht, die Ansicht, die Sie in onCreateView () aufblasen, als Ziel für den Hintergrund zu verwenden, anstatt das "Fenster" (activity.getWindow ()) zu verwenden? Das hat bei mir funktioniert
Noya
3
Wie benutzt man es in Aktivitäten?
Mrid
17

Wenn Sie nur den Hintergrund des Fensters hinter Ihrer Aktivität verwischen möchten, können Sie diesen Aufruf innerhalb Ihrer Aktivität (oder einer beliebigen Klasse wie einem AlertDialog mit einem Fenster) verwenden.

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

Update: Dieses Flag war in Android 4.0 veraltet und funktioniert nicht mehr .

Idistisch
quelle
Genau das, wonach ich gesucht habe. Ich schätze es!
b_yng
Dies wird nicht mehr unterstützt.
Kaustubh
3
Wie andere gesagt haben, wird dies nicht mehr unterstützt. Dieser Beitrag ist 4 Jahre alt. Folgen Sie stattdessen dem Beitrag von B. Young.
Idistic
@Idistic, aber wenn Sie B. Youngs Beitrag folgen, müssen Sie die minimale SDK-Stufe auf 17 erhöhen: - /
portfoliobuilder
0

Blurry ist eine nette Option, mit der Sie leicht den gewünschten Effekt erzielen: https://github.com/wasabeef/Blurry

Schließen Sie nach dem Hinzufügen zum Projekt die Ansicht, die Sie verwischen möchten, in ein FrameLayout ein und verwenden Sie diese Zeile, wenn Sie verwischen möchten:

Blurry.with(this).radius(25).sampling(2).onto((ViewGroup) findViewById(R.id.viewToBlurWrapper));
Yovboy
quelle
1
Leider gibt es ein Problem mit dieser lib github.com/wasabeef/Blurry/issues/50 Auch in meiner App.
webrama.pl