توفير تنقل مخصّص إلى الخلف

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

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

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

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

تنفيذ ميزة الرجوع المخصّصة إلى الوراء

إنّ ComponentActivity، الفئة الأساسية لـ FragmentActivity وAppCompatActivity، تتيح لك التحكّم في سلوك زر الرجوع باستخدام OnBackPressedDispatcher، والذي يمكنك استرداده من خلال الاتصال بـ getOnBackPressedDispatcher().

يتحكّم OnBackPressedDispatcher في كيفية إرسال أحداث زر الرجوع إلى كائن OnBackPressedCallback واحد أو أكثر. تستخدم الدالة الإنشائية لـ OnBackPressedCallback قيمة منطقية لحالة التفعيل المبدئي. عند تفعيل معاودة الاتصال، أي أن isEnabled() تعرض true، يتصل المرسِل باستدعاء handleOnBackPressed() للتعامل مع حدث زر الرجوع. يمكنك تغيير الحالة المفعّلة من خلال الاتصال على الرقم setEnabled().

وتتم إضافة عمليات معاودة الاتصال باستخدام طرق addCallback. نقترح استخدام الطريقة addCallback() التي تتطلّب LifecycleOwner. ويضمن ذلك عدم إضافة OnBackPressedCallback إلا عندما تكون قيمة LifecycleOwner هي Lifecycle.State.STARTED. يؤدي النشاط أيضًا إلى إزالة عمليات استدعاء النتائج المسجَّلة عند تدمير LifecycleOwner المرتبطة بها، ما يمنع تسرُّب الذاكرة ويجعل LifecycleOwner مناسبًا للاستخدام في الأجزاء أو غيرها من مالكي مراحل النشاط التجاري التي لم يتجاوز عمرها النشاط.

في ما يلي مثال على تنفيذ معاودة الاتصال:

Kotlin

class MyFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // This callback is only 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
    }
    ...
}

Java

public class MyFragment extends Fragment {

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // This callback is only called when MyFragment is at least started
        OnBackPressedCallback callback = new OnBackPressedCallback(true /* enabled by default */) {
            @Override
            public void handleOnBackPressed() {
                // Handle the back button event
            }
        };
        requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);

        // The callback can be enabled or disabled here or in handleOnBackPressed()
    }
    ...
}

يمكنك تقديم العديد من عمليات معاودة الاتصال باستخدام addCallback(). عند إجراء ذلك، يتم استدعاء عمليات الاسترداد بترتيب معكوس بدءًا من ترتيب إضافتها، وتكون معاودة الاتصال التي تمت إضافتها هي المرة الأولى المتاحة للتعامل مع حدث زر الرجوع. على سبيل المثال، عند إضافة ثلاث استدعاءات باسم one وtwo وthree، بهذا الترتيب، سيتم استدعاؤها بالترتيب three وtwo وone.

تتّبع عمليات معاودة الاتصال نمط سلسلة المسؤولية. لا يتم استدعاء كل معاودة اتصال في السلسلة إلا إذا لم يتم تفعيل معاودة الاتصال السابقة. وهذا يعني أنّه في المثال السابق، لا يتم استدعاء معاودة الاتصال two إلا في حال عدم تفعيل معاودة الاتصال "three"، واستدعاء one لمعاودة الاتصال فقط في حال عدم تفعيل معاودة الاتصال "two".

تجدر الإشارة إلى أنّه عند إضافة معاودة الاتصال باستخدام addCallback()، لا تتم إضافته إلى سلسلة المسؤولية إلى أن يدخل LifecycleOwner الحالة Lifecycle.State.STARTED.

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

إذا أردت إزالة OnBackPressedCallback بالكامل، يمكنك الاتصال بـ remove(). في العادة، لا يكون هذا الإجراء ضروريًا، لأنّه تتم إزالة عمليات معاودة الاتصال تلقائيًا عند تدمير LifecycleOwner المرتبطة بها.

النشاط onBackPressed()

إذا كنت تستخدم onBackPressed() للتعامل مع أحداث زر الرجوع، ننصحك باستخدام OnBackPressedCallback بدلاً من ذلك. ولكن إذا لم تتمكن من إجراء هذا التغيير، يتم تطبيق القواعد التالية:

  • يتم تقييم جميع عمليات معاودة الاتصال المسجَّلة عبر addCallback عند الاتصال بـ super.onBackPressed().
  • في نظام التشغيل Android 12 (مستوى واجهة برمجة التطبيقات 32) والإصدارات الأقدم، يتم دائمًا تسمية onBackPressed، بغض النظر عن أي مثيل من OnBackPressedCallback مسجَّل.