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

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

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

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

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

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

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

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

Kotlin

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
    }
    ...
}

Java

public class MyFragment extends Fragment {

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

        // This callback will only be 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()، لا تتم إضافة معاودة الاتصال إلى سلسلة المسؤولية إلى أن يتم إدخال حالة Lifecycle.State.STARTED.LifecycleOwner

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

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

النشاط onBackPressed()

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

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