يتم تعتيم النوافذ

في Android 12، تتوفّر واجهات برمجة التطبيقات العامة تطبيق تأثيرات تمويه النوافذ، مثل تمويه الخلفية وتمويه الخلفية

يتم استخدام عمليات تعتيم النوافذ، أو عمليات تعتيم النوافذ المتقاطعة، لتمويه الشاشة خلف نافذة معينة. هناك نوعان من تعتيم النوافذ، يمكن استخدامهما لتحقيق التأثيرات البصرية:

  • يتيح لك تمويه الخلفية إنشاء نوافذ ذات خلفيات مموّهة. مما يخلق تأثير زجاج بلوري.

  • يتيح لك خيار التمويه خلف تمويه الشاشة بأكملها خلف نافذة (مربّع حوار). مما يخلق عمق تأثير المجال.

ويمكن استخدام التأثيرَين بشكل منفصل أو مجمّعَين، كما هو موضّح في الشكل التالي:

تمويه الخلفية فقط

a‏

تمويه خلفي فقط

ب

تمويه الخلفية وتمويه الخلفية

ج

الشكل 1. تمويه الخلفية فقط (a)، تمويه الخلفية فقط (b)، تمويه الخلفية وتمويه الخلفية (c)

تعمل ميزة تمويه النوافذ عبر النوافذ، ما يعني أنّها تعمل أيضًا عند يظهر تطبيق آخر وراء نافذتك. ويختلف هذا التأثير عن تأثير عرض التمويه، ما يؤدي إلى تمويه المحتوى داخل النافذة نفسها. يعتبر تمويه النوافذ ومفيد لمربعات الحوار والأوراق السفلية والنوافذ العائمة الأخرى.

التنفيذ

مطوّرو التطبيقات

على مطوّري التطبيقات توفير نصف قطر تمويه لإنشاء تأثير تمويه. يتحكم نصف قطر التمويه في مدى كثافة التمويه، أي كلما زاد نصف القطر زادت كثافة التمويه. ويعني التمويه بقيمة 0 بكسل عدم التمويه. للتمويه في الخلف، نصف قطر يبلغ 20 بكسل يوفر عمقًا جيدًا للحقل، بينما تضيف الخلفية نصف قطر التعتيم 80 بكسل إلى تأثير زجاج بلوري جيد. تجنُّب التمويه أن يكون نصف القطر أعلى من 150 بكسل، لأنّ ذلك سيؤثر في الأداء بشكل كبير

اختَر تمويهًا لتحقيق تأثير التمويه المطلوب وزيادة إمكانية القراءة. نصف قطر تكملة بطبقة نصف شفافة من اللون.

تعتيم الخلفية

استخدِم تمويه الخلفية على النوافذ العائمة لإنشاء تأثير خلفية نافذة. وهي صورة مموَّهة للمحتوى الأساسي لإضافة خلفية مموَّهة لنافذتك، عليك اتّباع الخطوات التالية:

  1. طلب Window#setBackgroundB لإدارةRadius(int) من أجل ضبط نصف قطر تمويه الخلفية أو في مظهر النافذة، اضبط R.attr.windowBackgroundB لإدارةRadius.

  2. اضبط R.attr.windowIsTranslucent. على "صحيح" لجعل النافذة شفافة. يتم رسم التمويه تحت النافذة. لذا يجب أن تكون النافذة شبه شفافة للسماح بإظهار التمويه.

  3. يمكنك اختياريًا استدعاء Window#setBackgroundDrawableResource(int) من أجل إضافة خلفية نافذة مستطيلة قابلة للرسم بلون شبه شفاف. يمكنك بدلاً من ذلك ضبط R.attr.windowBackground في مظهر النافذة.

  4. بالنسبة إلى نافذة ذات زوايا مستديرة، حدد الزوايا المستديرة منطقة معتمة من خلال ضبط ShapeDrawable تتضمّن زوايا مستديرة كخلفية نافذة قابلة للرسم.

  5. يمكنك التعامل مع حالات تفعيل التمويه وإيقافها. يُرجى الرجوع إلى إرشادات استخدام تمويه النوافذ في التطبيقات. للحصول على المزيد من المعلومات.

تمويه خلفي

يؤدي التمويه خلف الشاشة إلى تمويه الشاشة بالكامل خلف النافذة. يتم استخدام هذا التأثير لتوجيه انتباه المستخدم نحو محتوى النافذة من خلال تمويه أي عنصر على الشاشة خلف النافذة.

لتمويه المحتوى خلف النافذة، اتّبِع الخطوات التالية:

  1. إضافة FLAG_BLUR_BEHIND إلى علامات النافذة، لتفعيل التمويه خلفه. أو، في مظهر النافذة، قم بتعيين R.attr.windowBourBehindEnabled.

  2. الاتصال بالرقم WindowManager.LayoutParams#setBlurBehindRadius تعيين تمويه خلف نصف القطر. أو، في مظهر النافذة، قم بتعيين R.attr.windowBourBehindRadius.

  3. يمكنك اختياريًا تحديد مقدار خفيف تكميلي.

  4. يمكنك التعامل مع حالات تفعيل التمويه وإيقافها. يُرجى الرجوع إلى إرشادات استخدام تمويه النوافذ في التطبيقات. للحصول على المزيد من المعلومات.

إرشادات حول استخدام تمويه النوافذ في التطبيقات

يعتمد دعم تمويه النوافذ على ما يلي:

  • إصدار Android: تتوفر واجهات برمجة التطبيقات لتمويه النوافذ على نظام التشغيل Android 12 فقط أعلى. تحقَّق من حزمة تطوير البرامج (SDK) للجهاز الخاصة بإصدار Android.

  • أداء الرسومات: قد تختار الأجهزة ذات وحدات معالجة الرسومات الأقل أداءً عدم دعم تمويه نوافذ الفيديو.

  • حالة النظام: قد يوقف خادم النظام تمويه النوافذ مؤقتًا في أثناء وضع توفير شحن البطارية مثلاً، وأثناء تشغيل أنواع نوعًا من محتوى الفيديو أو بسبب تجاوز أحد مطوّري البرامج.

لجعل تطبيقك متوافقًا مع إصدارات Android والأجهزة وحالات النظام، اتّبِع الإرشادات التالية:

  • إضافة مستمِع من خلال WindowManager#addCrossWindowB لإدارةEnabledListener لتلقّي إشعار عند تفعيل تمويه النافذة أو إيقافه. بالإضافة إلى ذلك، استخدام WindowManager#isCrossWindowBlurEnabled لطلب البحث ما إذا كان خيار تمويه النوافذ مفعّلاً حاليًا أم لا.

  • تنفيذ نسختين لخلفية النافذة لاستيعاب الإصدارات المفعَّلة أو حالة إيقاف تعتيم النوافذ.

    عند تفعيل التمويه، يجب أن تكون خلفية النافذة شبه شفافة لإنشاء التمويه المرئي وفي هذه الحالة، عندما يتم إيقاف عمليات التمويه، يتم عرض محتوى النافذة مباشرةً مع محتوى النافذة الأساسية، مما يؤدي إلى نافذة متداخلة أقل وضوحًا. لتجنُّب هذا التأثير، عند تعتيم النافذة معطَّلة، يمكنك تعديل واجهة المستخدم للتطبيق على النحو التالي:

    • لتمويه الخلفية، عليك زيادة ألفا خلفية النافذة. قابل للرسم، مما يجعلها أكثر تعتيمًا.

    • للتعتيم في الخلف، أضِف طبقة خافتة مع زيادة تعتيم الشاشة.

مثال على تمويه الخلفية وتمويه الخلفية

يقدّم هذا القسم مثالاً عمليًا لنشاط يستخدم كلاً من التمويه. إلى الخلف وتمويه الخلفية.

المثال التالي على MainActivity.java هو مربّع حوار يتضمّن تمويهًا. خلف نصف قطر يبلغ 20 بكسل ونصف قطر تمويه الخلفية 80 بكسل. تحتوي على زوايا دائرية، محدَّدة في ملف xml، في خلفية النافذة قابلة للرسم. ذلك بشكل صحيح تتعامل مع إصدارات مختلفة من 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 وحدة بكسل مستقلة الكثافة على النحو التالي:

<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 افتراضي تنشئه باستخدام المحاكي مع النافذة يحجبها.

بدون زوايا مستديرة

لا يؤدي تعديل خيار التمويه إلى تفعيل ميزة التمويه.

  • التحقق مما إذا كان الجهاز في وضع توفير شحن البطارية أو ما إذا كان يستخدم النفقات المتعددة الوسائط. وقد يتم أيضًا إيقاف تمويه النوافذ على بعض أجهزة التلفزيون أثناء تشغيل الفيديو.

تم رسم تمويه الخلفية بملء الشاشة، وليس ضمن حدود النافذة

لا يتم تطبيق الإشعارات من المستمع على الشاشة.

  • قد يتم تطبيق تحديثات المستمع على مثيل نافذة قديمة. تأكَّد مما إذا كانت النافذة تتعرض للتلف وإعادة إنشائها على الجانب الأيمن. تحديث المستمعين.