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

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

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

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

1

طمس وراء فقط

2

خلف وخلفية ضبابية

3

الشكل 1. تمويه الخلفية فقط (1) ، التمويه خلف فقط (2) ، تمويه الخلفية وتمويه الخلفية (3)

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

من المهم ملاحظة أن هذه الميزة تستخدم موارد GPU كبيرة. لذلك على الرغم من توفره لجميع أجهزة Android ، إلا أنه مدعوم فقط على تلك الأجهزة التي لديها طاقة GPU كافية.

تطبيق

مصنعي المعدات الأصلية والشركاء

يتم تعطيل تمويه النافذة افتراضيًا. لتمكين وظيفة التمويه على الأجهزة ، قم بما يلي:

  • تأكد من أن الجهاز يمكنه التعامل مع الحمل الإضافي لوحدة معالجة الرسومات - تكون عملية التمويه باهظة الثمن وفي الأجهزة ذات النهاية السفلية ، قد تتسبب في سقوط الإطارات. قم بتمكين هذا فقط على الأجهزة ذات طاقة GPU الكافية.
  • تأكد من أن librenderengine الخاص بك ينفذ منطق التعتيم - محرك العرض الافتراضي Android 12 يفعل ذلك ، ولكن أي محرك تصيير مخصص يجب أن ينفذ منطق التعتيم نفسه.
  • قم بتمكين التمويه عن طريق تعيين نظام قاذفة السطح التالي:
# enable surface flinger window blurs
PRODUCT_PROPERTY_OVERRIDES += \
       ro.surface_flinger.supports_background_blur=1

مطورو الطرف الثالث

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

  1. الجهاز يعمل بنظام Android 11 أو أقل. نظرًا لأن تمويه النافذة متاح فقط على الأجهزة التي تعمل بنظام Android 12 والإصدارات الأحدث ، يجب أن تنفذ التطبيقات تجربة بديلة خالية من الضبابية للأجهزة التي تعمل بنظام Android 11 والإصدارات الأقدم.
  2. لا يدعم الجهاز تمويه النوافذ لأنها باهظة الثمن ، لذلك قد تسقط الأجهزة المنخفضة الإطارات عند عرضها. في مثل هذه الحالات ، يجب أن توفر التطبيقات تجربة رجعية خالية من الضبابية.
  3. يقوم خادم النظام (على سبيل المثال ، أثناء وضع Battery Saver ، أو بسبب إعداد المطور أو وضع النفق) بتعطيل التمويه في وقت التشغيل.

تم الإبلاغ عن النقطتين 2 و 3 أعلاه بواسطة مستمع مسجل في WindowManager.addCrossWindowBlurEnabledListener . إذا كانت تطبيقاتك تستخدم واجهات برمجة التطبيقات الضبابية ، فقم بتسجيل هذا المستمع وقم بتحديث واجهة المستخدم الخاصة بك متى تم استدعاء المستمع ، إذا كنت تريد استخدام واجهة مستخدم مختلفة للحالات التي تم تمكين التمويه وتعطيل التعتيم. عندما يتم تسجيله ، يتم استدعاء المستمع فورًا للإبلاغ عما إذا تم تمكين التمويه حاليًا.

نفِّذ وظائف التمويه باستخدام الطرق التالية:

الأمثلة والمصدر

public class BlurActivity extends Activity {
   private final int mBackgroundBlurRadius = 150;
   private final Drawable mBackgroundDrawableWithBlur;
   private final Drawable mBackgroundDrawableNoBlur;

   private final int mBlurBehindRadius = 50;
   private final float mDimAmountWithBlur = 0.1f;
   private final float mDimAmountNoBlur = 0.6f;


   private Consumer<Boolean> mCrossWindowBlurEnabledListener = enabled -> {
       getWindow().setBackgroundDrawable(
               enabled ? mBackgroundDrawableWithBlur : mBackgroundDrawableNoBlur);
       getWindow().setDimAmount(enabled ? mDimAmountWithBlur : mDimAmountNoBlur);
   };

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

       mBackgroundDrawableWithBlur = getContext().getResources().getDrawable(
               R.drawable.window_background_with_blur);
       mBackgroundDrawableNoBlur = getContext().getResources().getDrawable(
               R.drawable.window_background_no_blur);

       if (Android version >= Android S) {
           getWindow().addFlags(
                   WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
           window.getAttributes().setBlurBehindRadius(mBlurBehindRadius);
           window.setBackgroundBlurRadius(mBackgroundBlurRadius);
           getWindow().getDecorView().addOnAttachStateChangeListener(
                                         new View.OnAttachStateChangeListener() {
                    @Override
                    public void onViewAttachedToWindow(View v) {
                        getWindowManager().addCrossWindowBlurEnabledListener(
                                                     blurEnabledListener);
                    }

                       @Override
                   public void onViewDetachedFromWindow(View v) {
                       getWindowManager().removeCrossWindowBlurEnabledListener(
                                                      blurEnabledListener);
                     }
           });
       }
       getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
   }

تشغيل تعتيم النافذة وإيقاف تشغيله

هناك طريقتان للسماح بطمس النوافذ وعدم السماح به.

  1. من واجهة المستخدم:

    الإعدادات -> النظام -> خيارات المطور -> العرض المسرع للأجهزة -> السماح بتمويه مستوى النافذة

  2. من الجهاز الطرفي (يجب عمل روت للجهاز):

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

يمكنك فقط تشغيل وظيفة تعتيم النافذة أو إيقاف تشغيلها إذا كان جهازك لديه القدرة على دعم التمويه. (لا يمكن للأجهزة التي لا تدعم تمويه النوافذ تمكين الميزة.) افتراضيًا ، يتم تمكين التمويه على الأجهزة التي تدعمها.

عند تمكين التمويه لأجهزتك ، ضع في اعتبارك أن أشياء أخرى مثل وضع توفير البطارية أو أنفاق الوسائط المتعددة يمكنها تعطيلها. يتم تمكين التمويه عند استيفاء جميع الشروط الضرورية - فهي مدعومة ولا شيء يعطلها. لمعرفة ما إذا كانت الحالة الحالية لوظيفة التعتيم "ممكّنة" ، استخدم الأمر adb shell wm disable-blur .

تصديق

للتأكد من أن إصدار ميزات التمويه الخاص بك يعمل على النحو الذي تريده ، قم بتنفيذ منطق واجهة المستخدم بحيث يعيد رسم عناصر واجهة المستخدم كلما blurEnabled (كما ورد من خلال addCrossWindowBlurEnabledListener ).

  1. افتح واجهة المستخدم التي بها تمويه.
  2. استخدم الخطوات الموضحة لتشغيل وإيقاف تشغيل تعتيم النافذة من واجهة المستخدم أو CLI.
  3. تحقق من أن واجهة المستخدم تتغير من وإلى واجهة غير واضحة كما هو متوقع.

استكشاف الأخطاء وإصلاحها

استخدم ما يلي كدليل لاستكشاف الأخطاء وإصلاحها أثناء التحقق من الصحة.

لم يتم رسم ضبابية

  • تحقق من تمكين التمويه حاليًا (وأن أجهزتك يدعمها) إما باستخدام CLI أو الانتقال إلى الإعدادات .

    1. استخدم الأمر adb shell wm disable-blur ، الذي يطبع ما إذا كانت التمويه مدعومة على هذا الجهاز وما إذا كانت ممكَّنة حاليًا.
    2. انتقل إلى الإعدادات -> النظام -> خيارات المطور -> العرض المسرع للأجهزة -> السماح بتمويه مستوى النافذة . إذا لم تتمكن من العثور على الخيار هناك ، فهذا يعني أن التمويه غير مدعوم على جهازك.
  • تأكد من تعيين لون خلفية نافذة شفافة ؛ لون خلفية نافذة معتم يخفي (يغطي) المنطقة المموهة.

جهاز الاختبار لا يدعم تمويه النوافذ

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

لا زوايا مستديرة

  • حدد الزوايا الدائرية عن طريق تعيين خلفية نافذة قابلة للرسم - Window#setBackgroundDrawable . هذا يحدد مخطط منطقة التمويه.

لا يؤدي تحديث خيار المطور إلى تمكين التمويه

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

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

  • تأكد من تمييز نافذتك على أنها عائمة - android:windowIsFloating
  • تأكد من أنك قمت بتعيين خلفية نافذة قابلة للرسم - Window#setBackgroundDrawable . هذا يحدد مخطط منطقة التمويه.

لا يتم تطبيق التحديثات من المستمع على الشاشة

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