विंडो को धुंधला करना

Android 12 में, विंडो ब्लर करने वाले इफ़ेक्ट लागू करने के लिए पब्लिक एपीआई उपलब्ध हैं. जैसे, बैकग्राउंड को धुंधला करना या बैकग्राउंड को धुंधला करना.

विंडो को धुंधला करने या क्रॉस-विंडो को धुंधला करने के लिए, किसी विंडो के पीछे की स्क्रीन को धुंधला किया जाता है. विंडो को धुंधला करने के दो तरीके हैं. इनका इस्तेमाल करके, अलग-अलग विज़ुअल इफ़ेक्ट बनाए जा सकते हैं:

  • बैकग्राउंड धुंधला करें सुविधा की मदद से, धुंधले बैकग्राउंड वाली विंडो बनाई जा सकती हैं. इससे, फ़्रॉस्टेड ग्लास जैसा इफ़ेक्ट मिलता है.

  • पीछे धुंधला करने की सुविधा से, डायलॉग (डायलॉग) विंडो के पीछे की पूरी स्क्रीन को धुंधला किया जा सकता है. इससे फ़ील्ड इफ़ेक्ट की गहराई का पता चलता है.

इन दोनों इफ़ेक्ट का इस्तेमाल अलग-अलग या एक साथ किया जा सकता है, जैसा कि इस इमेज में दिखाया गया है:

सिर्फ़ बैकग्राउंड को धुंधला करने की सुविधा

a

सिर्फ़ पीछे धुंधला करें

पीछे की चीज़ों को धुंधला करना और बैकग्राउंड को धुंधला करना

c

पहला डायग्राम. सिर्फ़ बैकग्राउंड धुंधला करें (a), सिर्फ़ पीछे की तरफ़ धुंधला करें (b), बैकग्राउंड और पीछे की तरफ़ धुंधला करें (c)

विंडो को धुंधला करने की सुविधा सभी विंडो पर काम करती है. इसका मतलब है कि यह तब भी काम करती है, जब आपकी विंडो के पीछे कोई दूसरा ऐप्लिकेशन हो. यह इफ़ेक्ट, धुंधला करने वाले रेंडर इफ़ेक्ट से अलग होता है. यह इफ़ेक्ट, उसी विंडो में अंदर मौजूद कॉन्टेंट को धुंधला करता है. विंडो को धुंधला करने की सुविधा का इस्तेमाल, डायलॉग बॉक्स, बॉटम शीट, और अन्य फ़्लोटिंग विंडो के लिए किया जा सकता है.

लागू करना

ऐप्लिकेशन डेवलपर

ऐप्लिकेशन डेवलपर को धुंधला करने का इफ़ेक्ट बनाने के लिए, धुंधला करने की त्रिज्या की जानकारी देनी होगी. ब्लर रेडियस से यह कंट्रोल होता है कि ब्लर कितना घना है, इसका मतलब है कि रेडियस जितना ज़्यादा होगा यानी ब्लर कितना घना होगा. ब्लर इफ़ेक्ट 0 पिक्सल का मतलब है कि धुंधला करने की ज़रूरत नहीं है. बैकग्राउंड धुंधला करने के लिए, 20 पिक्सल का रेडियस फ़ील्ड इफ़ेक्ट की अच्छी डेप्थ बनाता है. वहीं, बैकग्राउंड धुंधला करने का रेडियस 80 पिक्सल का एक अच्छा फ़्रॉस्टेड ग्लास इफ़ेक्ट देता है. धुंधला करने का दायरा 150 पिक्सल से ज़्यादा न रखें, क्योंकि इससे परफ़ॉर्मेंस पर काफ़ी असर पड़ेगा.

अपनी पसंद के मुताबिक धुंधला करने का इफ़ेक्ट पाने और कॉन्टेंट को पढ़ने में आसानी बनाने के लिए, धुंधला करने के दायरे की वैल्यू चुनें. साथ ही, रंग की पारदर्शी लेयर का इस्तेमाल करें.

बैकग्राउंड को धुंधला करें

फ़्लोटिंग विंडो पर बैकग्राउंड धुंधला करने की सुविधा का इस्तेमाल करके, विंडो के बैकग्राउंड का इफ़ेक्ट बनाएं. यह इफ़ेक्ट, विंडो में मौजूद कॉन्टेंट की धुंधली इमेज होती है. अपनी विंडो के लिए धुंधला बैकग्राउंड जोड़ने के लिए, यह तरीका अपनाएं:

  1. बैकग्राउंड को धुंधला करने की रेडियस सेट करने के लिए, Window#setbackgroundBlurRadious(int) को कॉल करें. इसके अलावा, विंडो थीम में R.attr.windowBackgroundBlurRadius सेट करें.

  2. विंडो को पारदर्शी बनाने के लिए, R.attr.windowIsTranslucent को सही पर सेट करें. ब्लर इफ़ेक्ट को विंडो की सतह के नीचे खींचा जाता है, ताकि उसे साफ़ तौर पर देखा जा सके.

  3. इसके अलावा, पारदर्शी रंग वाला रेक्टैंगल विंडो बैकग्राउंड जोड़ने के लिए, Window#setbackgroundDrawableResource(int) को कॉल करें. इसके अलावा, विंडो थीम में R.attr.windowBackground सेट करें.

  4. गोल कोनों वाली विंडो के लिए, धुंधले किए गए हिस्से के लिए गोल कोने तय करें. इसके लिए, विंडो के बैकग्राउंड ड्रॉआउट के तौर पर, गोल कोने वाले ShapeDrawable को सेट करें.

  5. धुंधला करने की सुविधा चालू और बंद होने की स्थितियों को मैनेज करें. ज़्यादा जानकारी के लिए, ऐप्लिकेशन में विंडो को धुंधला करने की सुविधा इस्तेमाल करने के दिशा-निर्देश सेक्शन देखें.

पीछे की इमेज को धुंधला करना

बैकग्राउंड को धुंधला करने की सुविधा से, विंडो के पीछे की पूरी स्क्रीन धुंधली हो जाती है. इस इफ़ेक्ट का इस्तेमाल विंडो के पीछे की स्क्रीन पर मौजूद किसी भी चीज़ को धुंधला करके, उपयोगकर्ता का ध्यान विंडो के कॉन्टेंट की ओर ले जाने के लिए किया जाता है.

अपनी विंडो के पीछे मौजूद कॉन्टेंट को धुंधला करने के लिए, यह तरीका अपनाएं:

  1. बैकग्राउंड को धुंधला करने के लिए, विंडो फ़्लैग में FLAG_BLUR_BEHIND जोड़ें. इसके अलावा, विंडो थीम में R.attr.windowBlurBehindEnabled सेट भी किया जा सकता है.

  2. त्रिज्या के पीछे धुंधलापन सेट करने के लिए, कॉल करें WindowManager.LayoutParams#setBlurBehindRadius. इसके अलावा, विंडो की थीम में R.attr.windowBब्लरBehindRadios भी सेट किया जा सकता है.

  3. अगर आप चाहें, तो ज़्यादा कम कीमत का इस्तेमाल करें.

  4. धुंधला करने की सुविधा चालू और बंद की गई स्थितियों को मैनेज करें. ज़्यादा जानकारी के लिए, ऐप्लिकेशन में विंडो धुंधला करने की सुविधा इस्तेमाल करने के दिशा-निर्देश सेक्शन देखें.

ऐप्लिकेशन में विंडो को धुंधला करने की सुविधा इस्तेमाल करने के लिए दिशा-निर्देश

विंडो को धुंधला करने की सुविधा इन बातों पर निर्भर करती है:

  • Android वर्शन: Windows ब्लर एपीआई सिर्फ़ Android 12 और उसके बाद वाले वर्शन के लिए उपलब्ध है. Android वर्शन के लिए, डिवाइस का SDK टूल देखें.

  • ग्राफ़िक की परफ़ॉर्मेंस: हो सकता है कि जिन डिवाइसों में जीपीयू की परफ़ॉर्मेंस अच्छी न हो उन पर विंडो को धुंधला करने की सुविधा काम न करे.

  • सिस्टम की स्थिति: हो सकता है कि सिस्टम सर्वर, रनटाइम के दौरान विंडो को धुंधला करने की सुविधा को कुछ समय के लिए बंद कर दे. उदाहरण के लिए, बैटरी सेवर मोड के दौरान, कुछ तरह के वीडियो कॉन्टेंट को चलाते समय या डेवलपर के बदलाव करने की वजह से.

अपने ऐप्लिकेशन को Android वर्शन, डिवाइसों, और सिस्टम की स्थितियों के हिसाब से बनाने के लिए, इन दिशा-निर्देशों का पालन करें:

  • विंडो को धुंधला करने की सुविधा चालू या बंद होने पर, आपको सूचना देने के लिए, WindowManager#addWindowBlurEnabledListener की मदद से लिसनर जोड़ें. इसके अलावा, WindowManager#isCrossWindowBlurEnabled का इस्तेमाल करके यह पता लगाएं कि फ़िलहाल विंडो धुंधला करने की सुविधा चालू है या नहीं.

  • विंडो को धुंधला करने की सुविधा को चालू या बंद करने के लिए, उसके बैकग्राउंड के दो वर्शन लागू करें.

    धुंधला करने की सुविधा चालू होने पर, विंडो का बैकग्राउंड पारदर्शी होना चाहिए, ताकि धुंधला दिखाई दे. इस स्थिति में, जब धुंधला करने की सुविधा बंद हो जाती है, तब विंडो का कॉन्टेंट सीधे तौर पर मौजूद विंडो के कॉन्टेंट से ओवरलैप हो जाता है. इस वजह से, ओवरलैप होने वाली विंडो को पढ़ा नहीं जा सकता. ऐसे किसी असर से बचने के लिए, विंडो को धुंधला करने की सुविधा बंद होने पर, ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) को इस तरह से बदलें:

    • बैकग्राउंड धुंधला करने के लिए, विंडो के बैकग्राउंड के ऐल्फ़ा को बढ़ाएं, ताकि वह ज़्यादा अपारदर्शी हो जाए.

    • ऑब्जेक्ट के पीछे के हिस्से को धुंधला करने के लिए, ज़्यादा धुंधला करने वाली लेयर जोड़ें.

पीछे धुंधला करने और बैकग्राउंड को धुंधला करने का उदाहरण

इस सेक्शन में ऐसी गतिविधि का उदाहरण दिया गया है जिसमें बैकग्राउंड को धुंधला करने के साथ-साथ, धुंधला करने की सुविधा भी इस्तेमाल की जाती है.

MainActivity.java का यह उदाहरण एक डायलॉग है, जिसमें बैकग्राउंड के धुंधले होने का दायरा 20 पिक्सल और बैकग्राउंड के धुंधले होने का दायरा 80 पिक्सल है. इसमें राउंड किए गए कोने होते हैं, जिन्हें विंडो के बैकग्राउंड ड्रॉबल में एक्सएमएल में तय किया जाता है. यह अलग-अलग Android वर्शन, अलग-अलग डिवाइसों (जो शायद विंडो को धुंधला करने की सुविधा के साथ काम न करते हों) और रनटाइम में धुंधला करने की सुविधा चालू या बंद करने के बदलावों को सही तरीके से मैनेज करता है. यह पक्का करता है कि विंडो के बैकग्राउंड के ड्रॉबल अल्फा और विंडो के मंद होने की मात्रा में बदलाव करके, डायलॉग बॉक्स का कॉन्टेंट उन सभी स्थितियों में पढ़ा जा सके.

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

विंडो के लिए गोल कोने बनाने के लिए, हम res/drawable/window_background.xml में विंडो के बैकग्राउंड को ShapeDrawable के तौर पर तय करते हैं. इसमें गोल कोने और रेडियस 20 dp होता है. इसे इस तरह से तय किया जाता है:

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

विंडो को धुंधला करने पर, गतिविधि के नीचे मौजूद विंडो का कॉन्टेंट भी धुंधला हो जाता है. धुंधली इमेज को इस गतिविधि विंडो के नीचे दिखाया जाता है. इसलिए, गतिविधि विंडो को पारदर्शी होना चाहिए, ताकि धुंधलापन दिख सके. विंडो को पारदर्शी बनाने के लिए, हम ऐक्टिविटी थीम में R.attr.windowIsTranslucent को इस तरह सेट करते हैं:

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

ओईएम और पार्टनर

किसी डिवाइस की विंडो को धुंधला करने के लिए, ओईएम को यह एलान करना होगा कि डिवाइस में विंडो को धुंधला करने की सुविधा काम करती है.

यह देखने के लिए कि आपके डिवाइस पर विंडो को धुंधला करने की सुविधा काम करती है या नहीं, यह तरीका अपनाएं:

  • पक्का करें कि डिवाइस, जीपीयू के अतिरिक्त लोड को मैनेज कर सकता है. हो सकता है कि कम क्षमता वाले डिवाइस, ज़्यादा लोड को हैंडल न कर पाएं. इस वजह से, फ़्रेम नहीं दिख सकते. सिर्फ़ उन डिवाइसों पर विंडो धुंधला करने की सुविधा चालू करें जिन पर जीपीयू की ज़रूरत के हिसाब से क्षमता हो.

  • अगर आपके पास पसंद के मुताबिक बनाया गया रेंडर इंजन है, तो पक्का करें कि आपका रेंडर इंजन, धुंधला करने का लॉजिक लागू करता हो. Android 12 का डिफ़ॉल्ट रेंडर इंजन, BlurFilter.cpp में धुंधला करने का लॉजिक लागू करता है.

यह पक्का करने के बाद कि आपके डिवाइस में विंडो को धुंधला करने की सुविधा काम कर सकती है, इस सरफ़ेस फ़्लिंगर sysprop को सेट करें:

PRODUCT_VENDOR_PROPERTIES += \
       ro.surface_flinger.supports_background_blur=1

पुष्टि करें

यह पुष्टि करने के लिए कि आपकी ऐप्लिकेशन विंडो, धुंधला करने की सुविधा चालू और बंद करने के बीच स्विच करते समय सही तरीके से काम करती है, यह तरीका अपनाएं:

  1. वह यूज़र इंटरफ़ेस (यूआई) खोलें जिसमें धुंधलापन है.

  2. विंडो को धुंधला करने की सुविधा को चालू या बंद करके, विंडो को धुंधला करने की सुविधा को चालू या बंद करें.

  3. पुष्टि करें कि विंडो का यूज़र इंटरफ़ेस (यूआई), उम्मीद के मुताबिक धुंधला हो गया है और फिर से साफ़ हो गया है.

विंडो को धुंधला करने की सुविधा को चालू या बंद करना

यह देखने के लिए कि विंडो ब्लर इफ़ेक्ट के साथ विंडो कैसे रेंडर होती है या नहीं, नीचे दिए गए तरीकों में से किसी एक का इस्तेमाल करके धुंधला करने की सुविधा को चालू या बंद करें:

  • 'डेवलपर के लिए सेटिंग और टूल' से:

    सेटिंग -> सिस्टम -> डेवलपर के लिए सेटिंग और टूल -> हार्डवेयर से तेज़ रेंडरिंग -> विंडो के लेवल पर धुंधला करने की अनुमति दें

  • रूट किए गए डिवाइस पर टर्मिनल से:

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

यह देखने के लिए कि आपके Android 12 और उसके बाद के वर्शन वाले डिवाइस पर विंडो को धुंधला करने की सुविधा काम करती है या नहीं और फ़िलहाल यह सुविधा चालू है या नहीं, रूट किए गए डिवाइस पर adb shell wm disable-blur चलाएं.

समस्या का हल

पुष्टि के दौरान समस्या हल करने के लिए, यहां दी गई गाइड का इस्तेमाल करें.

धुंधला नहीं किया गया

  • पुष्टि करें कि फ़िलहाल धुंधला करने की सुविधा चालू है और आपका हार्डवेयर इसके साथ काम करता है. विंडो को धुंधला करने की सुविधा को चालू और बंद करना लेख पढ़ें.

  • पक्का करें कि आपने विंडो के लिए पारदर्शी बैकग्राउंड कलर सेट किया हो. अपारदर्शी विंडो के बैकग्राउंड का रंग, धुंधला किए गए हिस्से को छिपा देता है.

टेस्ट डिवाइस पर, विंडो को धुंधला करने की सुविधा काम नहीं करती

  • Android 12 एम्युलेटर पर अपने ऐप्लिकेशन की जांच करें. Android एमुलेटर सेट अप करने के लिए, Android एमुलेटर सेट अप करना लेख पढ़ें. एम्युलेटर की मदद से बनाए गए किसी भी Android वर्चुअल डिवाइस से, विंडो को धुंधला किया जा सकता है.

कोई गोलाकार कोने नहीं

डेवलपर के लिए सेटिंग और टूल को अपडेट करने से, धुंधला करने की सुविधा चालू नहीं होती है

  • देखें कि डिवाइस बैटरी की बचत करने वाले मोड में है या नहीं या फिर मल्टीमीडिया टनलिंग का इस्तेमाल कर रहा है या नहीं. कुछ टीवी डिवाइसों पर, वीडियो चलाने के दौरान विंडो को धुंधला करने की सुविधा भी बंद हो सकती है.

बैकग्राउंड को धुंधला करने के लिए, फ़ुलस्क्रीन पर बैकग्राउंड का इस्तेमाल किया जा सकता है, विंडो की सीमाओं के अंदर नहीं

Listener से मिलने वाले अपडेट, स्क्रीन पर लागू नहीं होते

  • हो सकता है कि लिसनर के अपडेट, पुरानी विंडो के इंस्टेंस पर लागू हो रहे हों. देखें कि क्या विंडो खत्म हो रही है और इसे सही लिसनर अपडेट के साथ फिर से बनाया जा रहा है.