Sfocature finestre

In Android 12, le API pubbliche sono disponibili implementare effetti di sfocatura delle finestre, ad esempio la sfocatura dello sfondo e quella posteriore.

Le sfocature delle finestre, o cross-window, vengono utilizzate per sfocare lo schermo dietro il una determinata finestra. Esistono due tipi di sfocature delle finestre, che possono essere utilizzati per ottenere effetti visivi:

  • La sfocatura sfondo ti consente di creare finestre con sfondi sfocati. creando un effetto vetro satinato.

  • Sfocatura dietro ti consente di sfocare l'intero schermo dietro una finestra (finestra di dialogo). creando un effetto profondità di campo.

I due effetti possono essere usati separatamente o combinati, come mostrato nella figura seguente:

solo sfocatura sfondo

a

sfoca solo dietro

B

sfocatura posteriore e sfocatura dello sfondo

C

Figura 1. Solo sfocatura sfondo (a), solo sfocatura sfondo (b), sfocatura dello sfondo e sfocatura dello sfondo (c)

La funzionalità di sfocatura delle finestre funziona su tutte le finestre, il che significa che funziona anche quando c'è un'altra app dietro la finestra. Questo effetto è diverso da quello effetto di rendering sfocato, che sfoca i contenuti all'interno della stessa finestra. Le sfocature delle finestre sono utili per finestre di dialogo, fogli inferiori e altre finestre mobili.

.

Implementazione

Sviluppatori di app

Gli sviluppatori di app devono fornire un raggio di sfocatura per creare un effetto di sfocatura. Il raggio di sfocatura controlla la densità della sfocatura, ovvero più alto è il raggio, più densa è la sfocatura. Una sfocatura pari a 0 px indica che non è prevista alcuna sfocatura. Per ottenere una sfocatura dello sfondo, 20 px crea un buon effetto di profondità di campo, mentre uno sfondo un raggio di sfocatura di 80 px crea un buon effetto vetro satinato. Evita la sfocatura raggi superiori a 150 px, in quanto ciò influisce notevolmente sul rendimento.

Per ottenere l'effetto di sfocatura desiderato e aumentare la leggibilità, scegli una sfocatura valore del raggio completato da uno strato di colore traslucido.

Sfocatura sfondo

Usa la sfocatura dello sfondo sulle finestre mobili per creare un effetto di sfondo delle finestre che è un'immagine sfocata dei contenuti sottostanti. Per aggiungere uno sfondo sfocato per la finestra:

  1. Richiama Window#setBackgroundBlurRadius(int) per Impostare un raggio di sfocatura dello sfondo. In alternativa, imposta R.attr.windowBackgroundBlurRadius nel tema della finestra.

  2. Imposta R.attr.windowIsTranslucent su true per rendere la finestra traslucida. La sfocatura è disegnata sotto la finestra superficie, pertanto la finestra deve essere traslucida per rendere visibile la sfocatura.

  3. Facoltativamente, chiama Window#setBackgroundDrawableResource(int) per aggiungi uno sfondo rettangolare di una finestra disegnabile con un colore traslucido. In alternativa, imposta R.attr.windowBackground nel tema della finestra.

  4. Per una finestra con angoli arrotondati, determina gli angoli arrotondati per area sfocata impostando un elemento ShapeDrawable con angolo arrotondati come drawable sullo sfondo della finestra.

  5. Gestire gli stati di attivazione e disattivazione della sfocatura. Consulta le Linee guida per l'uso della sfocatura delle finestre nelle app per ulteriori informazioni.

Sfocatura dietro

La sfocatura sullo sfondo sfoca l'intero schermo dietro la finestra. Questo effetto è usato per indirizzare l'attenzione dell'utente verso il contenuto della finestra sfocando qualsiasi elemento sullo schermo dietro la finestra.

Per sfocare i contenuti dietro la finestra:

  1. Aggiungi FLAG_BLUR_BEHIND alle bandiere delle finestre, per attivare la sfocatura sullo sfondo. Oppure, nel tema della finestra, imposta R.attr.windowBlur dalloEnabled.

  2. Chiama WindowManager.LayoutParams#setBlurBehindRadius per imposta una sfocatura dietro il raggio. Oppure, nel tema della finestra, imposta R.attr.windowBlur dalloRadius.

  3. Se vuoi, puoi scegliere una quantità di luminosità complementare.

  4. Gestire gli stati di attivazione e disattivazione della sfocatura. Consulta le Linee guida per l'uso della sfocatura delle finestre nelle app per ulteriori informazioni.

Linee guida per usare la sfocatura delle finestre nelle app

Il supporto per la sfocatura delle finestre dipende da quanto segue:

  • Versione Android: le API Windows Blur sono disponibili solo su Android 12 e in alto. Controlla se nell'SDK del dispositivo è disponibile la versione di Android.

  • Prestazioni grafiche: i dispositivi con GPU meno prestazioni potrebbero scegliere di non farlo supporta le sfocature delle finestre.

  • Stato del sistema: il server di sistema potrebbe disattivare temporaneamente le sfocature delle finestre all'indirizzo di autonomia, ad esempio durante la modalità di risparmio energetico e durante la riproduzione di tipi di contenuti video o a causa di un override dello sviluppatore.

Per rendere la tua app compatibile con più versioni di Android, dispositivi e stati del sistema, segui queste linee guida:

  • Aggiungi un listener tramite WindowManager#addCrossWindowBlurEnabledListener, per ricevere una notifica quando le sfocature della finestra sono attivate o disattivate. Inoltre, usa WindowManager#isCrossWindowBlurEnabled per eseguire query se le sfocature delle finestre sono attualmente attivate.

  • Implementa due versioni per lo sfondo della finestra, in modo da includere le funzionalità o disattivato delle sfocature delle finestre.

    Quando le sfocature sono attivate, lo sfondo della finestra deve essere traslucido la sfocatura visibile. In questo stato, quando le sfocature vengono disattivate, i contenuti della finestra si sovrappone direttamente al contenuto della finestra sottostante, rendendo il finestra sovrapposta meno leggibile. Per evitare questo effetto, quando la finestra si sfoca sono disattivate, adatta l'interfaccia utente dell'app come segue:

    • Per la sfocatura dello sfondo, aumenta l'alfa dello sfondo della finestra disegnabile, rendendola più opaca.

    • Per sfocare le immagini sullo sfondo, aggiungi un livello di attenuazione maggiore.

Esempio di sfocatura dietro e sfondo

Questa sezione fornisce un esempio pratico di un'attività che utilizza sia la sfocatura dietro e sfocature sullo sfondo.

Il seguente esempio di MainActivity.java è una finestra di dialogo con una sfocatura dietro un raggio di 20 px e un raggio di sfocatura dello sfondo di 80 px. Ha angoli arrotondati, definiti nel file XML nel drawable dello sfondo della finestra. Corretto versioni di Android diverse, dispositivi diversi (che potenzialmente non supporta le sfocature delle finestre) e le modifiche attivate o disattivate con la sfocatura runtime. Garantisce che i contenuti delle finestre di dialogo siano leggibili in una qualsiasi di queste condizioni regolando drawable alpha dello sfondo della finestra e quantità di attenuazione della finestra.

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

Per creare angoli arrotondati per la finestra, definiamo lo sfondo della finestra in res/drawable/window_background.xml come ShapeDrawable con angolo arrotondati con raggio di 20 dp, come segue:

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

Le sfocature delle finestre sfocano il contenuto della finestra sotto l'attività. La l'immagine sfocata viene disegnata sotto questa finestra dell'attività, quindi la finestra dell'attività deve essere trasparente per consentire la sfocatura visibile. Per rendere la finestra traslucida, impostiamo R.attr.windowIsTranslucent in tema dell'attività come segue:

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

OEM e partner

Per avere la sfocatura delle finestre su un dispositivo, l'OEM deve dichiarare che il dispositivo supporta le sfocature delle finestre.

Per verificare se il dispositivo è in grado di supportare le sfocature delle finestre, procedi nel seguente modo:

  • Assicurati che il dispositivo sia in grado di gestire il carico aggiuntivo della GPU. Dispositivi di fascia inferiore potrebbe non essere in grado di gestire il carico aggiuntivo, causando la perdita dei frame. Attiva le sfocature delle finestre solo sui dispositivi testati con potenza GPU sufficiente.

  • Se disponi di un motore di rendering personalizzato, assicurati che quest'ultimo implementa la logica di sfocatura. Il dispositivo Android 12 predefinito motore di rendering implementa la logica di sfocatura in BlurFilter.cpp.

Dopo aver verificato che il dispositivo supporta le sfocature delle finestre, imposta quanto segue fetta di superficie sysprop:

PRODUCT_VENDOR_PROPERTIES += \
       ro.surface_flinger.supports_background_blur=1

Convalida

Per verificare che la finestra dell'app sia gestita correttamente quando passi da una sfocatura all'altra gli stati di attivazione e sfocatura, procedi nel seguente modo:

  1. Apri l'UI sfocata.

  2. Attiva o disattiva le sfocature delle finestre attivando e disattivando la sfocatura delle finestre.

  3. Verifica che l'interfaccia utente della finestra cambi da e verso uno stato sfocato come previsto.

Attivare e disattivare la sfocatura delle finestre

Per verificare come l'interfaccia utente delle finestre viene visualizzata con l'effetto sfocature delle finestre, attiva o disattiva le sfocature utilizzando uno dei seguenti metodi:

  • Dalle Opzioni sviluppatore:

    Impostazioni -> Sistema -> Opzioni sviluppatore -> Rendering con accelerazione hardware -> Consenti sfocature a livello di finestra

  • Dal terminale su un dispositivo rooted:

    adb shell wm disable-blur 1 # 1 disables window blurs, 0 allows them
    
di Gemini Advanced.

Per controllare se il tuo dispositivo Android 12 e versioni successive supporta la finestra sfocature e se le sfocature delle finestre sono attualmente attivate, esegui adb shell wm disable-blur su un dispositivo rooted.

Risoluzione dei problemi

Fai riferimento a quanto segue come guida per la risoluzione dei problemi durante la convalida.

Nessuna sfocatura tracciata

  • Verifica che le sfocature siano attualmente attivate e che il tuo hardware le supporti. Consulta l'articolo Attivare e disattivare la sfocatura della finestra.

  • Assicurati di impostare un colore di sfondo trasparente per la finestra. Una finestra opaca il colore di sfondo nasconde l'area sfocata.

Il dispositivo di test non supporta le sfocature delle finestre

  • Testa la tua applicazione sull'emulatore Android 12. Per configurare un emulatore Android, leggi l'articolo Configurare un emulatore Android. Qualsiasi dispositivo virtuale Android che crei con l'emulatore supporta la finestra sfocature.

Senza angoli arrotondati

L'aggiornamento dell'opzione sviluppatore non attiva le sfocature

  • Controlla se il dispositivo è in modalità di risparmio energetico o se è in uso tunnel multimediale. Su alcuni dispositivi TV, le sfocature delle finestre potrebbero essere disattivate anche durante la riproduzione dei video.

Sfocatura sfondo tracciata a schermo intero, non entro i margini della finestra

Gli aggiornamenti dal listener non vengono applicati sullo schermo

  • Gli aggiornamenti del listener potrebbero essere stati applicati a un'istanza della finestra precedente. Controlla se la finestra viene eliminata e ricreata con il aggiornamento listener.