Pencere bulanıklaştırma

Android 12'de, arka plan bulanıklaştırma ve arkadakileri bulanıklaştırma gibi pencere bulanıklaştırma efektlerini uygulamak için herkese açık API'ler kullanılabilir.

Pencere bulanıklaştırma veya pencereler arası bulanıklaştırma, belirli bir pencerenin arkasındaki ekranı bulanıklaştırmak için kullanılır. Farklı görsel efektler elde etmek için kullanılabilecek iki tür pencere bulanıklığı vardır:

  • Arka planı bulanıklaştırma, arka planı bulanık pencereler oluşturmanıza olanak tanıyarak buzlu cam efekti oluşturmanızı sağlar.

  • Arkayı bulanıklaştır seçeneği, bir (iletişim kutusu) pencerenin arkasında tüm ekranı bulanıklaştırmanıza olanak tanıyarak alan derinliği efekti oluşturur.

Bu iki efekt aşağıdaki şekilde gösterildiği gibi ayrı ayrı veya birlikte kullanılabilir:

yalnızca arka plan bulanıklaştırma

a

yalnızca arkadakini bulanıklaştır

arkaya bulanıklık ve arka plan bulanıklığı

c

Şekil 1. Yalnızca arka plan bulanıklaştırma (a), yalnızca arkadan bulanıklaştırma (b), arka plan bulanıklaştırma ve arkadan bulanıklık (c)

Pencere bulanıklaştırma özelliği, pencerelerde çalışır. Yani pencerenizin arkasında başka bir uygulama olduğunda da çalışır. Bu efekt, aynı pencerenin içindeki içeriği bulanıklaştıran bulanık oluşturma efektinden farklıdır. Pencere bulanıklaştırma özelliği iletişim kutuları, alt sayfalar ve diğer kayan pencerelerde işe yarar.

Uygulama

Uygulama geliştiriciler

Uygulama geliştiricilerin, bulanıklık efekti oluşturmak için bir bulanıklık yarıçapı sağlaması gerekir. Bulanıklaştırma yarıçapı, bulanıklaştırmanın ne kadar yoğun olacağını kontrol eder. Yani yarıçap ne kadar yüksek olursa bulanıklık o kadar yoğun olur. 0 piksel bulanıklık, bulanıklık olmadığı anlamına gelir. Arka plan bulanıklaştırma için 20 piksel yarıçapı iyi bir alan derinliği efekti oluştururken 80 piksel yarıçapı iyi bir buzlu cam efekti oluşturur. 150 pikselden yüksek bulanıklık yarıçaplarından kaçının. Aksi takdirde performans önemli ölçüde etkilenir.

İstediğiniz bulanıklık efektini elde etmek ve okunabilirliği artırmak için yarı saydam bir renk katmanı ile desteklenen bir bulanıklık yarıçapı değeri seçin.

Arka planı bulanıklaştırın

Yerleşik olmayan pencerelerde arka plan bulanıklaştırma özelliğini kullanarak, temel içeriğin bulanık bir resmi olan pencere arka planı efekti oluşturabilirsiniz. Pencerenize bulanıklaştırılmış bir arka plan eklemek için aşağıdakileri yapın:

  1. Arka plan bulanıklaştırma yarıçapını ayarlamak için Window#setBackgroundBlurRadius(int) yöntemini çağırın. Alternatif olarak, pencere temasında R.attr.windowBackgroundBlurRadius değerini ayarlayın.

  2. Pencereyi yarı saydam yapmak için R.attr.windowIsTranslucent değerini true olarak ayarlayın. Bulanıklaştırma, pencere yüzeyinin altına çizilir. Bu nedenle, bulanıklaştırmanın görünür olması için pencerenin yarı saydam olması gerekir.

  3. İsteğe bağlı olarak, yarı saydam renkli bir dikdörtgen pencere arka planı eklemek için Window#setBackgroundDrawableResource(int) yöntemini çağırın. Pencere temasında R.attr.windowBackground'ı da ayarlayabilirsiniz.

  4. Köşeleri yuvarlanmış bir pencerede, pencere arka planı çekilebilir olarak köşeleri yuvarlatılmış bir ShapeDrawable'ı ayarlayarak bulanık alanın yuvarlatılmış köşelerini belirleyin.

  5. Bulanıklaştırmanın etkin ve devre dışı durumlarını ele alın. Daha fazla bilgi için Uygulamalarda pencere bulanıklaştırmayı kullanmayla ilgili yönergeler bölümüne bakın.

Arka planı bulanıklaştır

Arka bulanıklık, pencerenin arkasındaki ekranın tamamını bulanıklaştırır. Bu efekt, ekranda pencerenin arkasındaki her şeyi bulanıklaştırarak kullanıcının dikkatini pencere içeriğine yönlendirmek için kullanılır.

Pencerenizin arkasındaki içeriği bulanıklaştırmak için aşağıdaki adımları uygulayın:

  1. Arkada bulanıklaştırma özelliğini etkinleştirmek için pencere işaretlerine FLAG_BLUR_BEHIND simgesini ekleyin. Pencere temasında R.attr.windowBlurBehindEnabled özelliğini de ayarlayabilirsiniz.

  2. Arka plan bulanıklığı yarıçapını ayarlamak için WindowManager.LayoutParams#setBlurBehindRadius işlevini çağırın. Alternatif olarak, pencere temasında R.attr.windowBlurBehindRadius değerini ayarlayın.

  3. İsteğe bağlı olarak, tamamlayıcı bir dim tutarı seçin.

  4. Bulanıklaştırmanın etkin ve devre dışı durumlarını ele alın. Daha fazla bilgi için Uygulamalarda pencere bulanıklaştırmayı kullanmayla ilgili yönergeler bölümüne bakın.

Uygulamalarda bulanıklaştırma özelliğini kullanmayla ilgili yönergeler

Pencere bulanıklaştırma desteği aşağıdakilere bağlıdır:

  • Android sürümü: Windows bulanıklaştırma API'leri yalnızca Android 12 ve sonraki sürümlerde kullanılabilir. Android sürümü için cihaz SDK'sını kontrol edin.

  • Grafik performansı: Daha düşük performanslı GPU'lara sahip cihazlar, pencere bulanıklaştırmalarını desteklememeyi seçebilir.

  • Sistem durumu: Sistem sunucusu, çalışma zamanında pencere bulanıklıklarını geçici olarak devre dışı bırakabilir (ör. pil tasarrufu modundayken, belirli türde video içerikleri oynatılırken veya geliştirici tarafından geçersiz kılındığında).

Uygulamanızı Android sürümleri, cihazlar ve sistem durumları genelinde uyumlu hale getirmek için aşağıdaki yönergeleri izleyin:

  • Pencere bulanıklaştırma etkinleştirildiğinde veya devre dışı bırakıldığında sizi bilgilendirmek için WindowManager#addCrossWindowBlurEnabledListener yoluyla bir işleyici ekleyin. Ayrıca, pencere bulanıklıklarının şu anda etkin olup olmadığını sorgulamak için WindowManager#isCrossWindowBlurEnabled değerini kullanın.

  • Pencere bulanıklaştırma durumunun etkin veya devre dışı olması için pencere arka planı için iki sürüm uygulayın.

    Bulanıklaştırma etkinleştirildiğinde, bulanıklaştırmanın görünür olması için pencere arka planı yarı saydam olmalıdır. Bu durumda, bulanıklık devre dışı bırakıldığında pencere içeriği doğrudan temel pencerenin içeriğiyle örtüşür ve örtüşen pencerenin okunabilirliği azalır. Bu tür bir etkiyi önlemek için, pencere bulanıklaştırma devre dışı bırakıldığında uygulamanın kullanıcı arayüzünü aşağıdaki gibi uyarlayın:

    • Arka plan bulanıklaştırma için pencere arka planı çizilebilir öğesinin alfa değerini artırarak daha opak hale getirin.

    • Arkada bulanıklık için daha yüksek loş miktarına sahip loş bir katman ekleyin.

Arkaya bulanıklaştırma ve arka planı bulanıklaştırma örneği

Bu bölümde, hem arka plan bulanıklaştırma hem de arka plan bulanıklaştırma özelliğini kullanan bir etkinliğin çalışan örneği verilmiştir.

Aşağıdaki MainActivity.java örneği, 20 piksel yarıçapında bulanıklaştırma ve 80 piksel arka plan bulanıklaştırma yarıçapı içeren bir iletişim kutusudur. Pencerenin arka planındaki çekince xml dosyası olarak tanımladığı yuvarlatılmış köşeleri vardır. Farklı Android sürümlerini, farklı cihazları (pencere bulanıklığını desteklemeyen cihazlar olabilir) ve çalışma zamanında bulanıklığın etkinleştirilmesi veya devre dışı bırakılması gibi değişiklikleri doğru şekilde yönetir. Pencere arka planı çizilebilir alfa değerini ve pencere karartma miktarını ayarlayarak iletişim kutusu içeriğinin bu koşullardan herhangi birinde okunabilir olmasını sağlar.

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

Pencerenin yuvarlatılmış köşeleri oluşturmak için res/drawable/window_background.xml ürününde pencere arka planını aşağıdaki gibi yuvarlatılmış köşeleri olan bir ShapeDrawable olarak tanımlıyoruz:

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

Pencere bulanıklaştırma, etkinliğin altındaki pencerenin içeriğini bulanıklaştırır. Bulanıklaştırılmış görüntü bu etkinlik penceresinin altına çizilir. Bu nedenle, bulanıklaştırmanın görünür olması için etkinlik penceresinin yarı saydam olması gerekir. Pencereyi yarı saydam yapmak için etkinlik temasında R.attr.windowIsTranslucent kodunu aşağıdaki şekilde ayarladık:

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

OEM'ler ve iş ortakları

Bir cihazda cam bulanıklaştırma uygulamak için OEM'nin, cihazın cam bulanıklaştırmayı desteklediğini beyan etmesi gerekir.

Cihazınızın pencere bulanıklaştırma özelliğini destekleyip desteklemediğini kontrol etmek için aşağıdakileri yapın:

  • Cihazın ekstra GPU yükünü kaldırabileceğinden emin olun. Daha alt segment cihazlar ekstra yükü kaldıramayabilir ve bu durum karelerin düşmesine neden olabilir. Pencere bulanıklaştırma özelliğini yalnızca yeterli GPU gücüne sahip test edilen cihazlarda etkinleştirin.

  • Özelleştirilmiş bir oluşturma motorunuz varsa oluşturma motorunuzun bulanıklık mantığını uyguladığından emin olun. Varsayılan Android 12 oluşturma motoru, BlurFilter.cpp'da bulanıklaştırma mantığını uygular.

Cihazınızın pencere bulanıklaştırmayı destekleyebildiğinden emin olduktan sonra aşağıdaki yüzey reklamını sysprop ayarlayın:

PRODUCT_VENDOR_PROPERTIES += \
       ro.surface_flinger.supports_background_blur=1

Doğrulama

Bulanıklaştırma etkin ve bulanıklık devre dışı durumları arasında geçiş yaparken uygulama pencerenizin uygun şekilde işlendiğini doğrulamak için aşağıdaki adımları uygulayın:

  1. Bulanıklaştırma efekti olan kullanıcı arayüzünü açın.

  2. Pencere bulanıklaştırma özelliğini açıp kapatarak pencere bulanıklaştırma özelliğini etkinleştirin veya devre dışı bırakın.

  3. Pencere kullanıcı arayüzünün bulanık duruma gidip gelip gelmediğini kontrol edin.

Pencere bulanıklaştırmayı açma ve kapatma

Pencere kullanıcı arayüzünün pencere bulanıklaştırma efektiyle nasıl oluşturulduğunu test etmek için aşağıdaki yöntemlerden birini kullanarak bulanıklaştırmayı etkinleştirin veya devre dışı bırakın:

  • Geliştirici seçenekleri'nden:

    Ayarlar -> Sistem -> Geliştirici seçenekleri -> Donanım hızlandırmalı oluşturma -> Pencere düzeyinde bulanıklıklara izin ver

  • Root erişimli bir cihazdaki terminalden:

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

Android 12 ve sonraki bir sürümün yüklü olduğu cihazınızın pencere bulaşmasını destekleyip desteklemediğini ve pencere bulanıklaştırma özelliğinin etkin olup olmadığını kontrol etmek için rootlanmış bir cihazda adb shell wm disable-blur komutunu çalıştırın.

Sorun giderme

Doğrulama sırasında karşılaşılan sorunları gidermek için kılavuz olarak aşağıdaki bilgileri kullanın.

Bulanıklaştırma uygulanmaz.

Test cihazında pencere bulanıklaştırma desteklenmiyor

  • Uygulamanızı Android 12 emülatöründe test edin. Android emülatörü ayarlamak için Android emülatörü kurma konusuna bakın. Emülatörle oluşturduğunuz tüm Android sanal cihazlar pencere bulanıklaştırmayı destekler.

Köşeleri yuvarlatılmış değil

Geliştirici seçeneğini güncellemek bulanıklıkları etkinleştirmez

  • Cihazın pil tasarrufu modunda mı yoksa multimedya tünelleme özelliğini kullanıp kullanmadığını kontrol edin. Bazı TV cihazlarında video oynatma sırasında pencere bulanıklaştırma da devre dışı bırakılabilir.

Arka plan bulanıklaştırma, pencere sınırları içinde değil, tam ekran olarak çizilir.

Dinleyicinin güncellemeleri ekrana uygulanmaz

  • Dinleyici güncellemeleri eski bir pencere örneğine uygulanıyor olabilir. Doğru işleyici güncellemesiyle pencerenin kaldırılıp kaldırılmadığını ve yeniden oluşturulup oluşturulmadığını kontrol edin.