Weichzeichnen des Fensters

In Android 12 stehen öffentliche APIs zur Implementierung von Weichzeichnereffekten wie dem Weichzeichnen des Hintergrunds und dem Weichzeichnen des Hintergrunds zur Verfügung.

Mit dem Weichzeichnen des Fensters oder des Fensterwechsels wird der Bildschirm hinter dem vorgegebenen Fenster unkenntlich gemacht. Es gibt zwei Arten von Fensterunschärfen, mit denen verschiedene visuelle Effekte erzielt werden können:

  • Mit der Hintergrundunschärfe können Sie Fenster mit unscharfen Hintergründen erstellen, um einen Milchglaseffekt zu erzielen.

  • Mit der Option Weichzeichnen können Sie den gesamten Bildschirm hinter einem Dialogfenster weichzeichnen und so einen Tiefenschärfe-Effekt erzielen.

Die beiden Effekte können separat oder kombiniert verwendet werden, wie in der folgenden Abbildung dargestellt:

nur Hintergrundunschärfe

a

Nur dahinter weichzeichnen

M

Hintergrund weichzeichnen und Hintergrund weichzeichnen

C

Abbildung 1. Nur Hintergrund weichzeichnen (a), nur Hintergrund weichzeichnen (b), Hintergrund und Hintergrund weichzeichnen (c)

Die Funktion zum Weichzeichnen von Fenstern funktioniert über alle Fenster hinweg, d. h. auch, wenn sich eine andere App hinter Ihrem Fenster befindet. Dieser Effekt ist nicht mit dem Rendereffekt „Unkenntlich machen“ identisch, bei dem die Inhalte innerhalb desselben Fensters unkenntlich gemacht werden. Fensterunschärfen sind nützlich für Dialogfelder, untere Sheets und andere schwebende Fenster.

Implementierung

App-Entwickler

App-Entwickler müssen einen Unkenntlichmachungsradius angeben, um einen Unkenntlichmachungseffekt zu erzielen. Der Weichzeichner-Radius bestimmt, wie intensiv die Unschärfe ist, d. h. je größer der Radius, desto dichter wird die Unschärfe. Bei einer Unschärfe von 0 Pixeln sind keine Unschärfen möglich. Für das Weichzeichnen im Hintergrund sorgt ein Radius von 20 px für einen guten Schärfentiefeeffekt, während ein Radius von 80 px für einen guten Milchglaseffekt sorgt. Vermeiden Sie Unschärferadien über 150 Pixel, da dies die Leistung erheblich beeinträchtigt.

Um den gewünschten Weichzeichnereffekt zu erzielen und die Lesbarkeit zu verbessern, wählen Sie einen Weichzeichnerwert in Kombination mit einer durchscheinenden Farbschicht aus.

Weichgezeichneter Hintergrund

Weichzeichnen des Hintergrunds für unverankerte Fenster ein, um einen Fensterhintergrundeffekt zu erzeugen, bei dem es sich um ein unscharfes Bild des zugrunde liegenden Inhalts handelt. So fügen Sie Ihrem Fenster einen weichgezeichneten Hintergrund hinzu:

  1. Rufen Sie Window#setBackgroundBlurRadius(int) auf, um einen Radius für die Hintergrundunschärfe festzulegen. Alternativ können Sie im Fensterdesign R.attr.windowBackgroundBlurRadius festlegen.

  2. Setzen Sie R.attr.windowIsTranslucent auf "true", um das Fenster durchscheinend zu machen. Die Unkenntlichmachung wird unter der Fensteroberfläche gezeichnet. Das Fenster muss also durchscheinend sein, damit die Unkenntlichmachung sichtbar ist.

  3. Rufen Sie optional Window#setBackgroundDrawableResource(int) auf, um ein rechteckiges Drawable für den Fensterhintergrund mit einer durchscheinenden Farbe hinzuzufügen. Sie können auch R.attr.windowBackground im Fensterdesign festlegen.

  4. Bestimmen Sie bei einem Fenster mit abgerundeten Ecken die abgerundeten Ecken für den verschwommenen Bereich, indem Sie ShapeDrawable mit abgerundeten Ecken als Zeichnungselement für den Fensterhintergrund festlegen.

  5. Umgang mit dem Status „Unkenntlich machen“ aktiviert und deaktiviert Weitere Informationen finden Sie im Abschnitt Richtlinien für die Verwendung von Fensterunkenntlichmachung in Apps.

Hintergrund weichzeichnen

Der Hintergrund verschwimmt den gesamten Bildschirm hinter dem Fenster weich. Mit diesem Effekt wird die Aufmerksamkeit des Nutzers auf den Inhalt des Fensters gelenkt, indem alles auf dem Bildschirm hinter dem Fenster unscharf gemacht wird.

So können Sie den Inhalt hinter Ihrem Fenster unkenntlich machen:

  1. Füge den Flags für das Fenster FLAG_BLUR_BEHIND hinzu, um ein Weichzeichnen des Hintergrunds zu ermöglichen. Sie können auch im Fensterdesign R.attr.windowBlurBehindEnabled festlegen.

  2. Rufen Sie WindowManager.LayoutParams#setBlurBehindRadius auf, um festzulegen, dass der Hintergrund weichgezeichnet werden soll. Alternativ können Sie im Fensterdesign R.attr.windowBlurBehindRadius festlegen.

  3. Optional können Sie einen ergänzenden Dim-Betrag auswählen.

  4. Umgang mit dem Status „Unkenntlich machen“ aktiviert und deaktiviert Weitere Informationen finden Sie im Abschnitt Richtlinien für die Verwendung von Fensterunkenntlichmachung in Apps.

Richtlinien für die Verwendung der Funktion zum Weichzeichnen des Fensters in Apps

Die Unterstützung für das Weichzeichnen von Fenstern hängt von folgenden Faktoren ab:

  • Android-Version: Die Windows-APIs sind nur unter Android 12 und höher verfügbar. Prüfen Sie im Geräte-SDK die Android-Version.

  • Grafikleistung: Geräte mit weniger leistungsfähigen GPUs unterstützen möglicherweise keine Fensterverpixelung.

  • Systemstatus: Der Systemserver kann das Weichzeichnen von Fenster während der Laufzeit vorübergehend deaktivieren, z. B. im Energiesparmodus, bei der Wiedergabe bestimmter Videoinhalte oder aufgrund einer Überschreibung durch den Entwickler.

Beachten Sie die folgenden Richtlinien, damit Ihre App mit allen Android-Versionen, Geräten und Systemstatus kompatibel ist:

  • Fügen Sie über WindowManager#addCrossWindowBlurEnabledListener einen Listener hinzu, der Sie benachrichtigt, wenn die Funktion zum Weichzeichnen von Fenstern aktiviert oder deaktiviert ist. Außerdem können Sie mit WindowManager#isCrossWindowBlurEnabled abfragen, ob die Funktion zum Weichzeichnen von Fenstern derzeit aktiviert ist.

  • Implementiere zwei Versionen für den Fensterhintergrund, um den aktivierten oder deaktivierten Zustand der Weichzeichnereffekte für das Fenster zu berücksichtigen.

    Wenn „Weichzeichnen“ aktiviert ist, sollte der Fensterhintergrund durchscheinend sein. Wenn in diesem Zustand das Weichzeichnen deaktiviert wird, überlappen sich die Inhalte des Fensters direkt mit den Inhalten des darunter liegenden Fensters, wodurch das überlappende Fenster weniger lesbar ist. Wenn Sie das Weichzeichnen des Fensters deaktivieren, können Sie dies vermeiden, indem Sie die UI der App so anpassen:

    • Für den Weichgezeichneten Hintergrund erhöhen Sie den Alphawert des Fensterhintergrunds, um ihn undurchsichtiger zu machen.

    • Wenn der Hintergrund weichgezeichnet werden soll, kannst du eine dunklere Ebene mit einem höheren Dimmgrad hinzufügen.

Beispiel für Weichzeichnen des Hintergrunds und des Hintergrunds

Dieser Abschnitt enthält ein Beispiel für eine Aktivität, bei der sowohl der Hintergrund als auch der Hintergrund weichgezeichnet werden.

Das folgende Beispiel für MainActivity.java ist ein Dialogfeld mit einem Unkenntlichmachungsradius von 20 px im Hintergrund und einem Unkenntlichmachungsradius von 80 px im Hintergrund. Es hat abgerundete Ecken, die im XML-Code im drawable-Element für den Fensterhintergrund definiert sind. Verschiedene Android-Versionen, verschiedene Geräte (die möglicherweise keine Funktion zum Weichzeichnen von Fenstern unterstützen) und Änderungen mit aktivierten oder deaktivierten Laufzeitverpixeln werden korrekt verarbeitet. Durch die Anpassung des Alphakanals des Fensterhintergrunds und der Dimmstärke des Fensters wird dafür gesorgt, dass der Dialoginhalt unter allen diesen Bedingungen lesbar ist.

public class MainActivity extends Activity {

    private final int mBackgroundBlurRadius = 80;
    private final int mBlurBehindRadius = 20;

    // We set a different dim amount depending on whether window blur is enabled or disabled
    private final float mDimAmountWithBlur = 0.1f;
    private final float mDimAmountNoBlur = 0.4f;

    // We set a different alpha depending on whether window blur is enabled or disabled
    private final int mWindowBackgroundAlphaWithBlur = 170;
    private final int mWindowBackgroundAlphaNoBlur = 255;

    // Use a rectangular shape drawable for the window background. The outline of this drawable
    // dictates the shape and rounded corners for the window background blur area.
    private Drawable mWindowBackgroundDrawable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mWindowBackgroundDrawable = getDrawable(R.drawable.window_background);
        getWindow().setBackgroundDrawable(mWindowBackgroundDrawable);

        if (buildIsAtLeastS()) {
            // Enable blur behind. This can also be done in xml with R.attr#windowBlurBehindEnabled
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);

            // Register a listener to adjust window UI whenever window blurs are enabled/disabled
            setupWindowBlurListener();
        } else {
            // Window blurs are not available prior to Android S
            updateWindowForBlurs(false /* blursEnabled */);
        }

        // Enable dim. This can also be done in xml, see R.attr#backgroundDimEnabled
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
    }

    /**
     * Set up a window blur listener.
     *
     * Window blurs might be disabled at runtime in response to user preferences or system states
     * (e.g. battery saving mode). WindowManager#addCrossWindowBlurEnabledListener allows to
     * listen for when that happens. In that callback we adjust the UI to account for the
     * added/missing window blurs.
     *
     * For the window background blur we adjust the window background drawable alpha:
     *     - lower when window blurs are enabled to make the blur visible through the window
     *       background drawable
     *     - higher when window blurs are disabled to ensure that the window contents are readable
     *
     * For window blur behind we adjust the dim amount:
     *     - higher when window blurs are disabled - the dim creates a depth of field effect,
     *       bringing the user's attention to the dialog window
     *     - lower when window blurs are enabled - no need for a high alpha, the blur behind is
     *       enough to create a depth of field effect
     */
    @RequiresApi(api = Build.VERSION_CODES.S)
    private void setupWindowBlurListener() {
        Consumer<Boolean> windowBlurEnabledListener = this::updateWindowForBlurs;
        getWindow().getDecorView().addOnAttachStateChangeListener(
                new View.OnAttachStateChangeListener() {
                    @Override
                    public void onViewAttachedToWindow(View v) {
                        getWindowManager().addCrossWindowBlurEnabledListener(
                                windowBlurEnabledListener);
                    }

                    @Override
                    public void onViewDetachedFromWindow(View v) {
                        getWindowManager().removeCrossWindowBlurEnabledListener(
                                windowBlurEnabledListener);
                    }
                });
    }

    private void updateWindowForBlurs(boolean blursEnabled) {
        mWindowBackgroundDrawable.setAlpha(blursEnabled && mBackgroundBlurRadius > 0 ?
                mWindowBackgroundAlphaWithBlur : mWindowBackgroundAlphaNoBlur);
        getWindow().setDimAmount(blursEnabled && mBlurBehindRadius > 0 ?
                mDimAmountWithBlur : mDimAmountNoBlur);

        if (buildIsAtLeastS()) {
            // Set the window background blur and blur behind radii
            getWindow().setBackgroundBlurRadius(mBackgroundBlurRadius);
            getWindow().getAttributes().setBlurBehindRadius(mBlurBehindRadius);
            getWindow().setAttributes(getWindow().getAttributes());
        }
    }

    private static boolean buildIsAtLeastS() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
    }
}

Um abgerundete Ecken für das Fenster zu erstellen, definieren wir den Fensterhintergrund in res/drawable/window_background.xml als ShapeDrawable mit abgerundeten Ecken und einem Radius von 20 dp:

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
    <corners android:radius="20dp"/>
    <solid android:color="#AAAAAA"/>
</shape>

Durch das Fenster wird der Inhalt des Fensters unter der Aktivität unkenntlich gemacht. Das unscharfe Bild wird unter diesem Aktivitätsfenster gezeichnet. Das Aktivitätsfenster muss also durchscheinend sein, damit die Unschärfe sichtbar ist. Um das Fenster durchscheinend zu machen, legen wir R.attr.windowIsTranslucent im Aktivitätsthema so fest:

<style name="Theme.BlurryDialog" parent="Theme.MaterialComponents.Dialog">
    <item name="android:windowIsTranslucent">true</item>
</style>

OEMs und Partner

Damit die Funktion „Fenster unkenntlich machen“ auf einem Gerät aktiviert werden kann, muss der OEM angeben, dass das Gerät diese Funktion unterstützt.

So prüfen Sie, ob Ihr Gerät die Funktion zum Weichzeichnen von Fenstern unterstützt:

  • Achten Sie darauf, dass das Gerät die zusätzliche GPU-Belastung bewältigen kann. Geräte mit geringerer Leistung können die zusätzliche Belastung möglicherweise nicht bewältigen, was zu Frame-Ausfällen führen kann. Aktivieren Sie das Weichzeichnen des Fensters nur auf getesteten Geräten mit ausreichender GPU-Leistung.

  • Wenn Sie eine benutzerdefinierte Rendering-Engine haben, muss diese die Logik zur Unkenntlichmachung implementieren. Die standardmäßige Render-Engine von Android 12 implementiert die Logik zur Unkenntlichmachung in BlurFilter.cpp.

Nachdem du sichergestellt hast, dass dein Gerät das Weichzeichnen des Fensters unterstützt, lege die folgende Oberflächenauswahl sysprop fest:

PRODUCT_VENDOR_PROPERTIES += \
       ro.surface_flinger.supports_background_blur=1

Zertifizierungsstufe

So können Sie prüfen, ob Ihr App-Fenster richtig gehandhabt wird, wenn Sie zwischen dem Status „Unkenntlich machen“ aktiviert und „Unkenntlich machen deaktiviert“ wechseln:

  1. Öffnen Sie die Benutzeroberfläche, die unkenntlich gemacht wurde.

  2. Sie können die Fensterunkenntlichmachung aktivieren oder deaktivieren.

  3. Prüfen Sie, ob sich die Benutzeroberfläche des Fensters wie erwartet in den Zustand „Unkenntlich gemacht“ ändert und wieder entfernt.

Weichzeichnen von Fenstern aktivieren und deaktivieren

Wenn Sie testen möchten, wie die Fenster-UI mit dem Weichzeichnereffekt gerendert wird, aktivieren oder deaktivieren Sie die Unschärfe mit einer der folgenden Methoden:

  • Über die Entwickleroptionen:

    Einstellungen -> System -> Entwickleroptionen -> Hardware beschleunigtes Rendering -> Unkenntlichmachung auf Fensterebene zulassen

  • Über das Terminal auf einem gerooteten Gerät:

    adb shell wm disable-blur 1 # 1 disables window blurs, 0 allows them

Wenn du prüfen möchtest, ob dein Gerät mit Android 12 oder höher die Funktion zum Weichzeichnen der Fenster unterstützt und ob diese Funktion derzeit aktiviert ist, führe adb shell wm disable-blur auf einem gerooteten Gerät aus.

Fehlerbehebung

Die folgenden Informationen können Ihnen bei der Fehlerbehebung während der Validierung helfen.

Keine Unschärfe

  • Prüfen Sie, ob die Unkenntlichmachungsfunktion derzeit aktiviert ist und von Ihrer Hardware unterstützt wird. Weitere Informationen finden Sie unter Weichzeichnen von Fenstern aktivieren und deaktivieren.

  • Legen Sie eine durchscheinende Hintergrundfarbe für das Fenster fest. Eine undurchsichtige Fensterhintergrundfarbe deckt den unkenntlich gemachten Bereich aus.

Testgerät unterstützt keine Fensterunschärfe

  • Testen Sie Ihre App im Android 12-Emulator. Informationen zum Einrichten eines Android-Emulators finden Sie unter Android-Emulator einrichten. Alle virtuellen Android-Geräte, die Sie mit dem Emulator erstellen, unterstützen die Fensterunschärfe.

Keine abgerundeten Ecken

Durch Aktualisieren der Entwickleroption werden keine Unkenntlichmachungen aktiviert

  • Prüfe, ob sich das Gerät im Energiesparmodus befindet oder Multimedia-Tunneling verwendet. Auf einigen Fernsehern wird die Fensterunkenntlichmachung möglicherweise auch während der Videowiedergabe deaktiviert.

Weichgezeichneter Hintergrund wird im Vollbildmodus und nicht innerhalb des Fensters angezeigt

Updates vom Listener werden nicht auf dem Bildschirm angewendet

  • Die Listener-Aktualisierungen werden möglicherweise auf eine alte Fensterinstanz angewendet. Prüfen Sie, ob das Fenster gelöscht und mit dem richtigen Listener-Update neu erstellt wird.