การนำทางด้านล่างและแท็บ
สร้างการนำทางหลายส่วนด้วย BottomNavigationView ที่เชื่อมต่อกับ NavController และแท็บที่ปัดได้ด้วย TabLayout, ViewPager2 และ TabLayoutMediator
การนำทางด้านล่างและแท็บ เป็นบทเรียน Android Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 5 จากทั้งหมด 5 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Android Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Android Academy มีบทเรียนทั้งหมด 5 บทเรียน
รูปแบบการนำทาง
รูปแบบที่ใช้กันทั่วไปสองรูปแบบสำหรับการนำทางระดับบนสุดในแอป Android:
- Bottom Navigation — สำหรับปลายทางหลัก 3–5 รายการ แสดงอยู่เสมอ เหมาะที่สุดสำหรับส่วนต่าง ๆ ที่มีความสำคัญเท่ากัน (เช่น หน้าหลัก การค้นหา โปรไฟล์)
- แท็บ — สำหรับเนื้อหาที่เกี่ยวข้องกันภายในหน้าจอเดียว (เช่น ทั้งหมด / กำลังทำ / เสร็จแล้ว) มักใช้ร่วมกับ 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>รายการในเมนู Bottom Nav
กำหนดรายการใน res/menu/bottom_nav_menu.xml โดย ID ของแต่ละรายการต้องตรงกับ ID ของปลายทางในกราฟการนำทาง:
<!-- 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
}
}
}
}ป้ายแจ้งเตือนบน Bottom Nav
แสดงป้ายแจ้งเตือนบนรายการของ bottom nav:
// 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 Nav เทียบกับแท็บ: วิธีเลือก
คู่มือฉบับย่อสำหรับเลือกรูปแบบที่เหมาะสม:
- ใช้ Bottom Navigation เมื่อ: มีปลายทางระดับบนสุด 3–5 รายการที่มีวัตถุประสงค์ต่างกัน (หน้าหลัก การค้นหา การแจ้งเตือน โปรไฟล์)
- ใช้แท็บ เมื่อ: ต้องกรองหรือจัดหมวดหมู่เนื้อหาประเภทเดียวกัน (งานทั้งหมด / กำลังทำ / เก็บถาวร)
- ใช้ทั้งสองรูปแบบร่วมกัน: ใช้ Bottom Nav สำหรับส่วนระดับบนสุด และใช้แท็บภายในส่วนนั้นเพื่อกรองย่อย
ตรวจสอบความเข้าใจ
คลาสใดใช้เชื่อม TabLayout กับ ViewPager2 และกำหนดป้ายชื่อแท็บ
ทบทวน: Bottom Navigation และแท็บ
การนำทางในแอปที่มีหลายส่วนอย่างถูกต้อง:
- BottomNavigationView — ปลายทาง 3–5 รายการที่มีความสำคัญเท่ากัน โดย ID ของเมนูต้องตรงกับ ID ของปลายทางในกราฟการนำทาง
setupWithNavController()— สลับแท็บและจัดการ back stack โดยอัตโนมัติ- ป้ายแจ้งเตือนด้วย
getOrCreateBadge() - TabLayout + ViewPager2 — มุมมองเนื้อหาเดียวกันที่ปัดได้และกรองได้
TabLayoutMediator— เชื่อมทั้งสองอย่างเข้าด้วยกันและกำหนดป้ายชื่อ
ถัดไป: การทดสอบหน่วยด้วย JUnit เพื่อให้โค้ดของคุณเชื่อถือได้
คำถามที่พบบ่อย
บทเรียน “การนำทางด้านล่างและแท็บ” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การนำทางด้านล่างและแท็บ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Android Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Android Academy มีบทเรียนทั้งหมด 5 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การนำทางด้านล่างและแท็บ”
สร้างการนำทางหลายส่วนด้วย BottomNavigationView ที่เชื่อมต่อกับ NavController และแท็บที่ปัดได้ด้วย TabLayout, ViewPager2 และ TabLayoutMediator คุณปฏิบัติ Android Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Android Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Android Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 5 จากทั้งหมด 5 บทเรียน
บทเรียน “การนำทางด้านล่างและแท็บ” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Android Academy นี้ได้ไหม
ได้ บทเรียน Android Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- พื้นฐาน Material Design
- ธีมและสไตล์
- มุมมองที่กำหนดเอง
- ภาพเคลื่อนไหวและการเปลี่ยนผ่าน
- การนำทางด้านล่างและแท็บ