0Pricing
Android Academy · درس

التنقّل السفلي وعلامات التبويب

طبّقوا التنقّل بين أقسام متعددة باستخدام BottomNavigationView المتصل بـ NavController، وعلامات تبويب قابلة للسحب باستخدام TabLayout وViewPager2 وTabLayoutMediator.

التنقّل السفلي وعلامات التبويب درس مجاني في Android Academy على CoddyKit. هذا هو الدرس 5 من أصل 5. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Android Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Android Academy 5 دروس في المجموع.

أنماط التنقل

نَمطان شائعان للتنقل على المستوى الأعلى في تطبيقات Android:

  • Bottom Navigation — لثلاث إلى خمس وجهات رئيسية. يكون ظاهرًا دائمًا. وهو الأنسب للأقسام متساوية الأهمية، مثل الصفحة الرئيسية والبحث والملف الشخصي.
  • Tabs — للمحتوى المرتبط داخل الشاشة نفسها، مثل الكل/النشطة/المكتملة. تُستخدم غالبًا مع ViewPager2 لدعم التمرير.

تخطيط BottomNavigationView

أضف BottomNavigationView وFragmentContainerView إلى تخطيط Activity:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/navHostFragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        app:navGraph="@navigation/nav_graph"
        app:defaultNavHost="true" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNav"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:menu="@menu/bottom_nav_menu" />

</LinearLayout>

عناصر قائمة التنقل السفلي

حدّد العناصر في res/menu/bottom_nav_menu.xml. يجب أن يطابق معرّف كل عنصر معرّف وجهة في مخطط التنقل:

<!-- res/menu/bottom_nav_menu.xml -->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/homeFragment"
        android:icon="@drawable/ic_home"
        android:title="Home" />
    <item
        android:id="@+id/searchFragment"
        android:icon="@drawable/ic_search"
        android:title="Search" />
    <item
        android:id="@+id/profileFragment"
        android:icon="@drawable/ic_person"
        android:title="Profile" />
</menu>

الربط بـ NavController

اربط BottomNavigationView بـ NavController داخل onCreate():

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val navHost = supportFragmentManager
            .findFragmentById(R.id.navHostFragment) as NavHostFragment
        val navController = navHost.navController

        binding.bottomNav.setupWithNavController(navController)

        // Hide bottom nav on detail screens:
        navController.addOnDestinationChangedListener { _, destination, _ ->
            binding.bottomNav.visibility = when (destination.id) {
                R.id.detailFragment -> View.GONE
                else -> View.VISIBLE
            }
        }
    }
}

الشارات في شريط التنقل السفلي

اعرض شارات الإشعارات على عناصر شريط التنقل السفلي:

// Show a numbered badge:
val badge = binding.bottomNav.getOrCreateBadge(R.id.homeFragment)
badge.number = 5
badge.isVisible = true

// Show dot badge (no number):
val dotBadge = binding.bottomNav.getOrCreateBadge(R.id.searchFragment)
dotBadge.isVisible = true

// Remove badge:
binding.bottomNav.removeBadge(R.id.homeFragment)

TabLayout

يعرض TabLayout علامات تبويب أفقية، ويُستخدم عادةً مع ViewPager2 لعرض محتوى قابل للتمرير:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

</LinearLayout>

ViewPager2 + FragmentStateAdapter

أنشئ محوّلًا يوفّر جزءًا لكل موضع من مواضع علامات التبويب:

class TasksPagerAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {

    override fun getItemCount() = 3

    override fun createFragment(position: Int): Fragment = when (position) {
        0 -> AllTasksFragment()
        1 -> ActiveTasksFragment()
        2 -> CompletedTasksFragment()
        else -> throw IllegalStateException("Unknown tab $position")
    }
}

TabLayoutMediator

اربط ViewPager2 وTabLayout باستخدام TabLayoutMediator:

// In Fragment.onViewCreated():
val adapter = TasksPagerAdapter(this)
binding.viewPager.adapter = adapter

TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
    tab.text = when (position) {
        0 -> "All"
        1 -> "Active"
        2 -> "Done"
        else -> ""
    }
}.attach()

// Disable swipe if needed:
binding.viewPager.isUserInputEnabled = false

علامة تبويب مع رموز

أضف رموزًا إلى علامات تبويب TabLayout:

TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
    when (position) {
        0 -> {
            tab.text = "Home"
            tab.setIcon(R.drawable.ic_home)
        }
        1 -> {
            tab.text = "Search"
            tab.setIcon(R.drawable.ic_search)
        }
        2 -> {
            tab.text = "Profile"
            tab.setIcon(R.drawable.ic_person)
        }
    }
}.attach()

حد الصفحات الموجودة خارج الشاشة

افتراضيًا، يحتفظ ViewPager2 بالصفحة المجاورة فقط في الذاكرة. ارفع قيمة offscreenPageLimit إذا أردت أن تظل علامات التبويب نشطة عند التبديل بينها:

// Keep 2 pages on each side alive:
binding.viewPager.offscreenPageLimit = 2

// Note: FragmentStateAdapter saves and restores state for off-screen
// fragments even when offscreenPageLimit is 1 (default).
// Only increase this when you need views (not just state) to survive.

التنقل السفلي أم علامات التبويب: كيفية الاختيار

دليل سريع لاختيار النمط المناسب:

  • استخدم Bottom Navigation عندما تكون لديك 3–5 وجهات رئيسية ذات أغراض مختلفة، مثل الصفحة الرئيسية والبحث والإشعارات والملف الشخصي.
  • استخدم Tabs عند تصفية النوع نفسه من المحتوى أو تصنيفه، مثل كل المهام/المهام النشطة/المهام المؤرشفة.
  • اجمع بينهما: استخدم Bottom Nav للأقسام الرئيسية، وTabs داخل القسم للتصفية الفرعية.

تحقق سريع

ما الفئة التي تربط TabLayout بـ ViewPager2 وتضبط تسميات علامات التبويب؟

مراجعة: التنقل السفلي وعلامات التبويب

تنفيذ التنقل بين الأقسام المتعددة بطريقة صحيحة:

  • BottomNavigationView — من 3 إلى 5 وجهات متساوية الأهمية، مع تطابق معرّفات القائمة مع معرّفات الوجهات في مخطط التنقل
  • setupWithNavController() — التبديل التلقائي بين علامات التبويب + مكدس الرجوع
  • الشارات باستخدام getOrCreateBadge()
  • TabLayout + ViewPager2 — طرق عرض قابلة للتمرير ومصفّاة للمحتوى نفسه
  • TabLayoutMediator — يربط بينهما ويضبط التسميات

التالي: اختبار الوحدات باستخدام JUnit للحفاظ على موثوقية الشيفرة.

الأسئلة الشائعة

هل درس «التنقّل السفلي وعلامات التبويب» مجاني؟

نعم — نص درس «التنقّل السفلي وعلامات التبويب» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Android Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Android Academy 5 دروس في المجموع.

ماذا ستتعلم في «التنقّل السفلي وعلامات التبويب»؟

طبّقوا التنقّل بين أقسام متعددة باستخدام BottomNavigationView المتصل بـ NavController، وعلامات تبويب قابلة للسحب باستخدام TabLayout وViewPager2 وTabLayoutMediator. تتمرن على Android Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Android Academy؟

لا تُشترط خبرة سابقة. Android Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 5 من أصل 5.

كم من الوقت يستغرق درس «التنقّل السفلي وعلامات التبويب»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Android Academy هذا؟

نعم. كل درس في Android Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. أساسيات Material Design
  2. Themes وStyles
  3. واجهات مخصّصة
  4. الرسوم المتحركة والانتقالات
  5. التنقّل السفلي وعلامات التبويب
← العودة إلى Android Academy