يتنقّل المستخدمون للخلف بين الشاشات باستخدام إيماءة الرجوع. تحتوي معظم أجهزة Android على زر رجوع (مادي أو برمجي أو مستند إلى الإيماءات). عادةً، لا يُنصح بإضافة زر رجوع إلى تطبيقك، ولكنّ الأجهزة التي تعمل بنظام التشغيل Android Automotive (AAOS) في وضع التوافق تستخدم زر رجوع خاصًا بالنظام. يتولّى هذا المكوّن عملية التنقّل، لذا لست بحاجة إلى إضافة مكوّن خاص بك. لمعرفة التفاصيل، يُرجى الاطّلاع على وضع التوافق في AAOS.
يحتفظ نظام التشغيل Android بذاكرة مؤقتة للخلف للوجهات أثناء تنقّل المستخدم
في تطبيقك. يتيح ذلك عادةً لنظام Android الانتقال بشكل صحيح إلى
الوجهات السابقة عند الضغط على زر الرجوع. ومع ذلك، هناك بعض الحالات التي قد يحتاج فيها تطبيقك إلى تنفيذ سلوك الرجوع الخاص به من أجل توفير أفضل تجربة ممكنة للمستخدم. على سبيل المثال، عند استخدام WebView،
قد ترغب في تجاوز سلوك زر الرجوع الافتراضي للسماح للمستخدم
بالانتقال مرة أخرى من خلال سجل تصفح الويب بدلاً من الشاشات السابقة
في تطبيقك.
تنفيذ ميزة "الرجوع" المخصّصة في Compose
في Jetpack Compose، يمكنك التعامل مع ميزة "التنقّل للخلف" المخصّصة باستخدام الدالة المركّبة BackHandler.
عند استخدام Navigation Compose، يمكنك عادةً استخدام
NavController.navigateUp() أو NavController.popBackStack()
للانتقال إلى الشاشة السابقة في سجلّ الرجوع. ومع ذلك، فإنّ BackHandler
مفيد في الحالات التي تريد فيها تنفيذ سلوك مخصّص عندما يضغط المستخدم على زر الرجوع في النظام أو يستخدم إيماءة الرجوع. على سبيل المثال، إذا كنت تعرض WebView في تطبيقك، قد تحتاج إلى السماح للمستخدمين بالرجوع إلى سجلّ التصفُّح عند الضغط على زر الرجوع في النظام.
الاستخدام الأساسي
في ما يلي مثال يوضّح كيفية اعتراض حدث الرجوع للتحكّم في الحالة المخصّصة (مثل تصغير لوحة):
@Composable fun MyScreen() { var isExpanded by remember { mutableStateOf(false) } // Intercept the back button or gesture only when isExpanded is true BackHandler(enabled = isExpanded) { // Collapsing the content disables this handler, so it does not // receive the next back event. isExpanded = false } if (isExpanded) { Text("Expanded content. Go back to collapse it.") } else { Button(onClick = { isExpanded = true }) { Text("Expand") } } }
اعتراض الشجرة القابلة للتركيب
إذا كان لديك عدة دوال مركّبة BackHandler مفعّلة على مستويات مختلفة من شجرة الدوال المركّبة، ستعترض الدالة الأعمق فقط حدث الرجوع.
تنفيذ التنقّل المخصّص للخلف باستخدام طرق العرض
يتيح لك الصنف الأساسي ComponentActivity لكل من FragmentActivity وAppCompatActivity التحكّم في سلوك زر الرجوع باستخدام OnBackPressedDispatcher الذي يمكنك استرداده من خلال استدعاء getOnBackPressedDispatcher().
يتحكّم OnBackPressedDispatcher في كيفية إرسال أحداث زر الرجوع
إلى عنصر واحد أو أكثر من عناصر OnBackPressedCallback. تتطلّب دالة الإنشاء لـ OnBackPressedCallback قيمة منطقية للحالة الأولية المفعَّلة. لن يستدعي برنامج المعالجة الدالة handleOnBackPressed() الخاصة بدالة رد الاتصال لمعالجة حدث زر الرجوع إلا عند تفعيل دالة رد الاتصال، مثلاً عندما تعرض الدالة isEnabled() القيمة true. يمكنك تغيير الحالة المفعّلة من خلال استدعاء
setEnabled().
تتم إضافة عمليات معاودة الاتصال باستخدام طرق addCallback. استخدِم طريقة
addCallback() التي تأخذ LifecycleOwner. بهذه الطريقة، لن تتم إضافة OnBackPressedCallback إلا عندما تكون قيمة LifecycleOwner هي Lifecycle.State.STARTED. يزيل النشاط أيضًا عمليات معاودة الاتصال المسجّلة عند إيقاف LifecycleOwner المرتبط بها، ما يمنع تسرُّب الذاكرة ويجعله مناسبًا للاستخدام في الأجزاء أو مالكي دورات الحياة الآخرين الذين يكون عمرهم أقصر من عمر النشاط.
في ما يلي مثال على تنفيذ دالة ردّ اتصال:
class MyFragment : Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // This callback will only be called when MyFragment is at least Started. val callback = requireActivity().onBackPressedDispatcher.addCallback(this) { // Handle the back button event } // The callback can be enabled or disabled here or in the lambda } ... }
يمكنك تقديم عدة دوال ردّ باستخدام addCallback().
عند إجراء ذلك، يتم استدعاء عمليات الاستدعاء بترتيب عكسي لترتيب إضافتها، أي أنّ عملية الاستدعاء التي تمت إضافتها في النهاية هي أول عملية استدعاء يتم منحها فرصة لمعالجة حدث زر الرجوع. على سبيل المثال، إذا أضفت ثلاث عمليات استدعاء باسم
one وtwo وthree بالترتيب، سيتم استدعاؤها بالترتيب
three وtwo وone على التوالي.
تتّبع عمليات الاستدعاء نمط
سلسلة المسؤولية. يتم استدعاء كل دالة رد اتصال في السلسلة فقط إذا لم يتم تفعيل دالة رد الاتصال السابقة. هذا يعني أنّه في المثال السابق، لن يتم استدعاء وظيفة رد الاتصال two إلا إذا لم يتم تفعيل وظيفة رد الاتصال three. لن يتم استدعاء دالة ردّ الاتصال one إلا إذا لم يتم تفعيل دالة ردّ الاتصال two، ويستمر هذا النمط مع أي دوال ردّ اتصال إضافية.
يُرجى العِلم أنّه عند إضافة معالج باستخدام addCallback()،
لا تتم إضافة معالج الردّ إلى سلسلة المسؤولية إلا بعد أن
يدخل LifecycleOwner في حالة
Lifecycle.State.STARTED.
ننصح بشدة بتغيير حالة التفعيل في الدالة التنفيذية عند الحاجة إلى إجراء تغييرات مؤقتة، لأنّ ذلك يحافظ على الترتيب الموضّح سابقًا، وهو أمر مهم بشكل خاص إذا كانت لديك دوال تنفيذية مسجّلة في عدة عناصر مالكة مختلفة ومتداخلة لدورة الحياة.
إذا أردت إزالة رقم إعادة الاتصال بالكامل، اتّصِل بالرقم
remove().
لا يكون ذلك ضروريًا عادةً لأنّه تتم إزالة عمليات الرجوع تلقائيًا عند إيقاف LifecycleOwner المرتبط بها.