OOZOU
تواصلوا معنا
العودة إلى المدونة

تشغيل Fragment للحصول على نتيجة باستخدام Navigation Component

تعرّفوا على طريقة تشغيل Fragment للحصول على نتيجة دون عناء باستخدام Navigation Component.

22 ديسمبر 2020
4 دقائق للقراءة
تشغيل Fragment للحصول على نتيجة باستخدام Navigation Component

مقدمة

تغيّر الكثير خلال السنتين الماضيتين في طريقة تطويرنا لتطبيقات Android. فلدينا الآن إطار أبسط لحقن التبعيات (dependency injection) هو Dagger-Hilt، ومكتبات AndroidX التي حسّنت استخدام كثير من مكوّنات Android، والـ coroutines التي أنقذتنا من جحيم الـ callbacks، ومكتبة ORM أفضل بكثير هي Room، ونعم، نظام تنقّل (navigation) أفضل بمراحل. ومن المشكلات الشائعة التي يواجهها المطوّرون خطأ 'unable to start activity'، الذي يظهر عادةً عندما يفشل التطبيق في تعيين NavController للـ activity. ودون أن نضيّع الكثير من وقتكم، لننتقل مباشرة إلى طريقة تشغيل fragment آخر للحصول على نتيجة منه.

فهم المشكلة

عند العمل مع Android Navigation Component، قد تواجهون استثناء IllegalStateException أثناء محاولة التنقل إلى fragment. يحدث هذا الخطأ عادةً لأن الـ fragment لا يملك NavController معيّنًا له. والـ NavController جزء أساسي من Navigation Component، فهو المسؤول عن إدارة التنقل بين الـ fragments. ومن دونه لا يستطيع Navigation Component تنفيذ عملية التنقل، فيظهر الخطأ.

العلاقة بين الـ Fragment والـ NavController

لكي يعمل Navigation Component بشكل صحيح، يجب أن يكون لكل fragment NavController معيّن. ويتحقق ذلك عادةً بإضافة الـ fragment إلى NavHostFragment، وهو نوع خاص من الـ fragments مصمَّم لاستضافة navigation graph. وعندما يكون الـ fragment جزءًا من NavHostFragment، يحصل تلقائيًا على نسخة الـ NavController، فيصبح التنقل سلسًا.

أما إذا لم يُضَف الـ fragment إلى NavHostFragment، فلن يكون له NavController. وغياب الـ NavController هو ما يطلق استثناء IllegalStateException، لأن Navigation Component لا يجد نسخة الـ NavController اللازمة للتنقل إلى الوجهة المطلوبة.

لنبدأ: start activity componentinfo

لنفترض أنكم تريدون الانتقال من Fragment A إلى Fragment B، وتريدون الحصول على نتيجة من Fragment B عند العودة إلى Fragment A. في هذه الحالة ستُعدّون Fragment A هكذا (وقد واجهت شخصيًا مشكلة في تمرير البيانات إلى الـ fragment السابق عندما كنت أعمل على مشروع مشابه): class FragmentA : Fragment override fun onViewCreatedview: View, savedInstanceState: Bundle? super.onViewCreatedview, savedInstanceState

class FragmentA : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        <strong>//Observe the result to be set by Fragment B in the stateHandle of the currentBackStackEntry
        val currentBackStackEntry = findNavController().</strong><strong><em>currentBackStackEntry
        </em></strong><strong>val savedStateHandle = currentBackStackEntry?.</strong><strong><em>savedStateHandle
        </em></strong><strong>savedStateHandle?.getLiveData<String>(RESULT_FROM_FRAGMENT_B)
            ?.observe(currentBackStackEntry, Observer { result ->
                print(result)
            })</strong>
    }

    private fun navigateToFragmentB() {
        val navDirection = FragmentADirection.actionFragmentAToFragmentB()
        findNavController().navigate(navDirection)
    }

    companion object {
        const val RESULT_FROM_FRAGMENT_B = "RESULT_FROM_FRAGMENT_B"
    }
}

ثم تُعدّون Fragment B ليعيّن النتيجة التي يراقبها Fragment A

class FragmentB : Fragment() {

    private fun navigateBackToFragmentA() {
        <strong>//Setting the result in the stateHandle of the previousBackStackEntry before navigating back to Fragment A
        //will allow Fragment A to access the result in the stateHandle of its currentBackStackEntry
        val savedStateHandle = findNavController().</strong><strong><em>previousBackStackEntry</em></strong><strong>?.</strong><strong><em>savedStateHandle
        </em></strong><strong>savedStateHandle?.set(FragmentA.RESULT_FROM_FRAGMENT_B, "result")
        findNavController().navigateUp()</strong>
    }
}

هذا كل شيء! يمكنكم بسهولة التنقل إلى أي fragment والحصول على النتيجة، عبر تعيينها في الـ stateHandle الخاص بـ previousBackStackEntry ومراقبتها في الـ stateHandle الخاص بـ currentBackStackEntry.

أفضل الممارسات

لتجنّب استثناء IllegalStateException وضمان تنقّل سلس بين الـ fragments، اتبعوا الممارسات التالية:

  1. استخدموا FragmentContainerView: بدلًا من استخدام FrameLayout في ملف الـ layout، اختاروا FragmentContainerView. فهذا الـ view مصمَّم خصيصًا لاحتواء NavHostFragment، ويسهّل تعيين نسخة الـ NavController.
  2. أنشئوا الـ NavController في onPostCreate(): في الـ MainActivity، استخدموا الدالة onPostCreate() لإنشاء نسخة الـ NavController. تُستدعى هذه الدالة بعد إنشاء الـ view الخاص بالـ activity، ما يضمن توفّر الـ NavController عند الحاجة إليه.
  3. اجعلوا الـ activity ترث من AppCompatActivity: تأكدوا من أن الـ activity الخاصة بكم ترث من AppCompatActivity، فهذا ضروري ليعمل Navigation Component بشكل صحيح.
  4. صحّحوا الإعدادات في Android Manifest: تأكدوا من أن ملف Android Manifest يتضمن الأذونات والـ activities والـ services والـ receivers والـ providers اللازمة. فهذا يساعد على تجنّب أي مشكلات متعلقة بالتنقل أثناء التشغيل.

باتباع هذه الممارسات، يمكنكم تجنّب استثناء IllegalStateException وضمان تنقّل تطبيقكم بسلاسة بين الـ fragments باستخدام Navigation Component.

Related Articles

كيف أصمّم برمجيات؟ دليل المبتدئين لأصحاب الأعمال

كيف أصمّم برمجيات؟ دليل المبتدئين لأصحاب الأعمال

تصميم البرمجيات عملية ممتعة لكنها معقدة، تتطلب الإبداع والتفكير المنطقي ومهارات حل المشكلات.

اقرأوا المزيد
مستقبل الحوسبة الطرفية: ما تحتاج الشركات إلى معرفته

مستقبل الحوسبة الطرفية: ما تحتاج الشركات إلى معرفته

يتطور المشهد الرقمي بسرعة، وعلى الشركات أن تتكيّف لتواكب الطلب المتزايد على السرعة والكفاءة والمعالجة في الوقت الفعلي.

اقرأوا المزيد
مستقبل قطاع التجزئة: الذكاء الاصطناعي والواقع المعزّز واتجاهات التحوّل الرقمي

مستقبل قطاع التجزئة: الذكاء الاصطناعي والواقع المعزّز واتجاهات التحوّل الرقمي

يتطور قطاع التجزئة بوتيرة غير مسبوقة بفضل الذكاء الاصطناعي (AI) والواقع المعزّز (AR) وتقنيات التحوّل الرقمي. فلم تعد المتاجر التقليدية مجرد أماكن لبيع المنتجات، بل أصبحت متاجر ذكية وتفاعلية.

اقرأوا المزيد

Have a Project in Mind?

Let's discuss how we can help bring your ideas to life with our expertise in web and mobile development.

ابدأوا المحادثةhello@oozou.com
OOZOU Logo

بانكوك · سنغافورة · هونغ كونغ

X
Facebook
Instagram
LinkedIn
OOZOU Co., Ltd.
548 One City Centre
Ploenchit Road
Bangkok 10330
Thailand
+66 2544 0000
hello@oozou.com

الخدمات

  • تطوير الويب
  • وكلاء الذكاء الاصطناعي والذكاء الاصطناعي التوليدي
  • تطوير تطبيقات الجوال
  • تحليلات البيانات وهندستها
  • تصميم تجربة المستخدم وواجهته (UX/UI) وتصميم المنتجات
  • التحوّل الرقمي

الشركة

  • من نحن
  • الوظائف
  • المدونة
  • دراسات الحالة
  • عروض حية
  • تعلّمت اليوم
  • تواصل معنا

المزيد

  • القطاعات
  • شبكة الشركاء
© 2026 OOZOU. جميع الحقوق محفوظة.
سياسة الخصوصيةمدونة قواعد السلوكسياسة مكافحة الرشوة والفساد