التعامل مع تغييرات الإعدادات

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

  • حجم عرض التطبيق
  • اتجاه الشاشة
  • حجم الخط ووزنه
  • اللغة
  • الوضع الداكن مقابل الوضع الفاتح
  • مدى توفّر لوحة المفاتيح

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

تتطلّب هذه المَعلمات عادةً تغييرات كبيرة بما يكفي في واجهة مستخدم تطبيقك، لذا يتضمّن نظام Android الأساسي آلية مصمّمة خصيصًا للتعامل مع هذه التغييرات. تُعرف هذه الآلية باسم إعادة إنشاء Activity.

إعادة إنشاء النشاط

يعيد النظام إنشاء Activity عند حدوث تغيير في الإعدادات. ولإجراء ذلك، يستدعي النظام onDestroy ويزيل مثيل Activity الحالي. بعد ذلك، يتم إنشاء مثيل جديد باستخدام onCreate، ويتم تهيئة مثيل Activity الجديد هذا باستخدام الإعدادات الجديدة والمعدَّلة. يعني هذا أيضًا أنّ النظام يعيد إنشاء واجهة المستخدم باستخدام الإعدادات الجديدة.

تعمل Activity عادةً كمضيف للعناصر القابلة للإنشاء. عند إعادة إنشاء Activity، يعيد Compose أيضًا إنشاء واجهة المستخدم باستخدام قيم الإعدادات الجديدة.

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

مثال على الأنشطة الترفيهية

لنفترض أنّ هناك دالة مركّبة تعرض عنوانًا ثابتًا باستخدام مصدر السلاسل النصية:

// In the res/values/strings.xml file
// <string name="compose">Jetpack Compose</string>

// In your Compose code
Text(
    text = stringResource(R.string.compose)
)

عند إنشاء Activity، يقرأ العنصر القابل للإنشاء Text الإعدادات الحالية (مثل اللغة) ويحلّ مورد السلسلة المناسب.

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

تؤدي عملية إعادة الإنشاء أيضًا إلى محو أي حالة تم الاحتفاظ بها كحقول في Activity.

للحفاظ على حالة واجهة المستخدم عند إجراء تغييرات في الإعدادات، استخدِم أنماط إدارة الحالة المقترَحة. استخدِم ViewModel للبيانات ومنطق النشاط التجاري، واستخدِم rememberSaveable لحالة مستوى واجهة المستخدم. باستخدام هذه الآليات، تظل حالتك محفوظة عند إعادة إنشاء Activity، بينما يتم تعديل واجهة المستخدم لتعكس الإعداد الجديد.

لمزيد من المعلومات حول حفظ الحالة في Compose، يُرجى الاطّلاع على حفظ حالة واجهة المستخدم في Compose.

توقّعات المستخدمين

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

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

  • تدوير الجهاز
  • تفعيل وضع النوافذ المتعددة
  • تغيير حجم التطبيق في وضع النوافذ المتعددة أو في نافذة حرة الشكل
  • طي جهاز قابل للطي مزوّد بشاشات عرض متعددة
  • تغيير مظهر النظام، مثل الوضع الداكن مقابل الوضع الفاتح
  • تغيير حجم الخط
  • تغيير لغة النظام أو التطبيق
  • توصيل لوحة مفاتيح خارجية أو قطع الاتصال بها
  • ربط قاعدة شحن أو إلغاء ربطها

هناك عدة طرق يمكنك اتّخاذها للحفاظ على الحالة ذات الصلة أثناء إعادة الإنشاء.Activity يعتمد اختيار أحدهما على نوع الحالة التي تريد الاحتفاظ بها:

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

للاطّلاع على تفاصيل حول واجهات برمجة التطبيقات الخاصة بكل من هذه الحالات، ومعرفة الوقت المناسب لاستخدام كل منها، راجِع مقالة حفظ حالات واجهة المستخدم.

حظر إعادة إنشاء النشاط

يمكنك منع إعادة إنشاء النشاط تلقائيًا عند إجراء تغييرات معيّنة في الإعدادات. في التطبيقات الحديثة التي تستخدم Compose فقط، تتم إعادة إنشاء واجهة المستخدم في كلتا الحالتين، ولكن يُنصح بالتعامل مع تغيير الإعدادات مباشرةً.

بشكلٍ تلقائي، يؤدي تغيير الإعداد إلى إجبار النظام على محو النشاط وإعادة إنشائه، بما في ذلك واجهة المستخدم وأي عناصر مشتقة من النشاط. إذا أعلنت أنّ نشاطك يتعامل مع تغيير الإعدادات بنفسه، سيمنع النظام ذلك. بدلاً من ذلك، يتم تعديل العنصر Configuration فقط، ويعيد Compose إنشاء واجهة المستخدم باستخدام القيم الجديدة.

تتعدّد مزايا التعامل مع تغييرات الإعدادات مباشرةً في Compose، ومنها:

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

لإيقاف إعادة إنشاء النشاط عند إجراء تغييرات معيّنة في الإعدادات، أضِف نوع الإعداد إلى android:configChanges في إدخال <activity> في ملف AndroidManifest.xml. تظهر القيم المحتمَلة في المستندات الخاصة بالسمة android:configChanges.

يؤدي رمز البيان التالي إلى إيقاف إعادة إنشاء Activity عند MyActivity عند تغيير اتجاه الشاشة وتوفُّر لوحة المفاتيح:

<activity
    android:name=".MyActivity"
    android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
    android:label="@string/app_name">

الاستجابة للتغييرات في الإعدادات

تتيح Jetpack Compose لتطبيقك الاستجابة بسهولة أكبر لتغييرات الإعدادات. ومع ذلك، إذا أوقفت إعادة إنشاء Activity لجميع تغييرات الإعدادات التي يمكن إيقافها، يجب أن يتعامل تطبيقك مع تغييرات الإعدادات بشكل صحيح.

يتوفّر العنصر Configuration في التسلسل الهرمي لواجهة مستخدم Compose مع LocalConfiguration المحلي للتركيب. وعندما تتغيّر، تتم إعادة إنشاء الدوال المركّبة التي تقرأ من LocalConfiguration.current. لمزيد من المعلومات حول طريقة عمل البيانات المحلية في التركيب، يمكنك الاطّلاع على البيانات ذات النطاق المحلي باستخدام CompositionLocal.

مثال

في المثال التالي، تعرض دالة قابلة للإنشاء تاريخًا بتنسيق محدّد. تتفاعل الدالة المركّبة مع تغييرات إعدادات اللغة في النظام من خلال استدعاء ConfigurationCompat.getLocales مع LocalConfiguration.current.

@Composable
fun DateText(year: Int, dayOfYear: Int) {
    val dateTimeFormatter = DateTimeFormatter.ofPattern(
        "MMM dd",
        ConfigurationCompat.getLocales(LocalConfiguration.current)[0]
    )
    Text(
        dateTimeFormatter.format(LocalDate.ofYearDay(year, dayOfYear))
    )
}

لتجنُّب إعادة إنشاء Activity عند تغيير اللغة، يجب أن يوقف المضيف Activity الذي يتضمّن رمز Compose إمكانية تغيير إعدادات اللغة. لإجراء ذلك، عليك ضبط android:configChanges على locale|layoutDirection.

تغييرات الإعدادات: المفاهيم الرئيسية وأفضل الممارسات

في ما يلي المفاهيم الأساسية التي يجب معرفتها عند إجراء تغييرات في الإعدادات:

  • عمليات الضبط: تحدّد عمليات ضبط الجهاز طريقة عرض واجهة المستخدم للمستخدم، مثل حجم عرض التطبيق أو اللغة أو مظهر النظام. في Compose، يمكنك الوصول إلى قيم الإعدادات باستخدام LocalConfiguration.
  • تغييرات الإعدادات: تتغيّر الإعدادات من خلال تفاعل المستخدم. على سبيل المثال، قد يغيّر المستخدم إعدادات الجهاز أو طريقة تفاعله معه. لا يمكن منع إجراء تغييرات في الإعدادات.
  • إعادة إنشاء Activity: تؤدي تغييرات الإعدادات إلى إعادة إنشاء Activity تلقائيًا. هذه آلية مدمَجة لإعادة تهيئة حالة التطبيق للإعداد الجديد.
  • تدمير Activity: يؤدي إعادة إنشاء Activity إلى تدمير النظام لمثيل Activity القديم وإنشاء مثيل جديد مكانه. أصبحت النسخة القديمة غير صالحة الآن. تجنَّب الاحتفاظ بمراجع لكائنات ذات نطاق دورة حياة يتجاوز نطاقها المقصود.
  • الحالة: لا تتوفّر الحالة في مثيل Activity القديم في مثيل Activity الجديد، لأنّهما مثيلا عنصر مختلفان. بدلاً من ربط الحالة بـ Activity، استخدِم واجهات برمجة التطبيقات المقترَحة للحفاظ على حالة التطبيق والمستخدم كما هو موضّح في حفظ حالات واجهة المستخدم.
  • إيقاف الميزة: يتطلّب إيقاف ميزة إعادة إنشاء النشاط لنوع من تغييرات الإعدادات أن يحدّث تطبيقك بشكل صحيح استجابةً للإعدادات الجديدة. لا يُنصح بذلك لمعظم تطبيقات Compose.

لتقديم تجربة جيدة للمستخدم، اتّبِع أفضل الممارسات التالية:

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

التعامل مع تغييرات الإعدادات المستندة إلى الحجم

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

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

حصر إعادة إنشاء النشاط عند إجراء تغييرات في الإعدادات استنادًا إلى الحجم

عند إيقاف Activity إعادة الإنشاء للتغييرات في الإعدادات المستندة إلى الحجم، لا يعيد النظام إنشاء Activity. بدلاً من ذلك، سيتلقّى مكالمة على الرقم Activity.onConfigurationChanged. سيتم إعادة إنشاء أي عناصر قابلة للإنشاء تقرأ LocalConfiguration.current تلقائيًا لتعكس الحجم الجديد.

يتم إيقاف إعادة إنشاء Activity لتغييرات الإعدادات المستندة إلى الحجم عند توفّر android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout" في ملف البيان.

مراجع إضافية

لمزيد من المعلومات حول التعامل مع تغييرات الإعدادات، يُرجى الاطّلاع على المراجع الإضافية التالية:

الوثائق

مشاهدة المحتوى