Navigation Component — คืออะไร, NavHost และ Navigation Graph

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-02-22 เวลาอ่าน: 7 นาที

Navigation Component คือไลบรารี Android Jetpack สำหรับการนำทางระหว่างหน้าจอของแอปพลิเคชัน คอมโพเนนต์นี้รวมศูนย์การจัดการสแตกของแฟรกเมนต์ ลิงก์ลึก และการส่งผ่านอาร์กิวเมนต์ เป็นส่วนหนึ่งของ Jetpack ตั้งแต่ปี 2018 และ Google แนะนำสำหรับโปรเจกต์ใหม่ทั้งหมด อ่านเพิ่มเติมใน คู่มือทางการของ Google

ประเด็นสำคัญ

  • Navigation Component — ไลบรารี Jetpack สำหรับการนำทางแบบรวมศูนย์ระหว่างหน้าจอ Android
  • NavGraph — ทรัพยากร XML ที่อธิบายหน้าจอทั้งหมดและการเชื่อมต่อระหว่างกัน
  • NavHostFragment — คอนเทนเนอร์ในเลย์เอาต์ของ Activity ที่แสดงหน้าจอการนำทางปัจจุบัน
  • NavController — ออบเจ็กต์ควบคุมการนำทาง: navigate, popBackStack, navigateUp
  • Safe Args — ปลั๊กอิน Gradle สำหรับการส่งผ่านอาร์กิวเมนต์ที่ปลอดภัยชนิดระหว่างหน้าจอ

Navigation Component คืออะไร?

Navigation Component คือไลบรารี Android Jetpack (androidx.navigation) ที่ให้ API แบบรวมสำหรับการนำทาง ประกอบด้วยสามองค์ประกอบหลัก: Navigation Graph (กราฟการนำทาง), NavHostFragment (คอนเทนเนอร์หน้าจอ) และ NavController (ตัวควบคุมการเปลี่ยนหน้า) คอมโพเนนต์นี้จัดการสแตกย้อนกลับโดยอัตโนมัติและรองรับลิงก์ลึก

ก่อน Navigation Component นักพัฒนาจัดการแฟรกเมนต์ด้วยตนเองผ่าน FragmentManager ส่งผลให้โค้ดกระจัดกระจาย: แต่ละหน้าจอมีกฎการนำทางของตัวเอง สถานะสแตกย้อนกลับแตกต่างกัน และลิงก์ลึกต้องมีการดำเนินการแยกต่างหาก Navigation Component รวมสถานการณ์เหล่านี้เข้าด้วยกัน ตามข้อมูลของ Google (2026) ไลบรารีนี้ติดตั้งใน 90% ของโปรเจกต์ Android ใหม่

Navigation Component ผสานรวมกับไลบรารี Jetpack อื่นๆ: LiveData, ViewModel, Material Design รองรับทั้งแฟรกเมนต์ XML และ Jetpack Compose ผ่านส่วนขยาย navigation-compose รุ่นเสถียร — 2.8.x (2025), Android เวอร์ชันขั้นต่ำ — API 14

NavGraph คือทรัพยากร XML (res/navigation/nav_graph.xml) ที่กำหนดหน้าจอทั้งหมดของแอปและการเชื่อมต่อระหว่างกัน แต่ละหน้าจอคือปลายทาง (destination) ซึ่งสามารถเป็น Fragment, Activity หรือ Composable การเชื่อมต่อระหว่างปลายทางคือการกระทำ (action) ที่กำหนดทิศทางการเปลี่ยนหน้า

xml

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    app:startDestination="@+id/homeFragment">

    <fragment
        android:id="@+id/homeFragment"
        android:name=".HomeFragment"
        android:label="หน้าแรก"
        tools:layout="@layout/fragment_home">
        <action
            android:id="@+id/action_home_to_detail"
            app:destination="@+id/detailFragment"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_left"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_right" />
    </fragment>

    <fragment
        android:id="@+id/detailFragment"
        android:name=".DetailFragment"
        android:label="รายละเอียด"
        tools:layout="@layout/fragment_detail">
        <argument android:name="itemId"
            app:argType="integer"
            android:defaultValue="0" />
    </fragment>
</navigation>

แอตทริบิวต์ startDestination กำหนดหน้าจอแรกที่แสดงเมื่อเริ่มต้น การกระทำกำหนดปลายทางเป้าหมายและแอนิเมชันเสริม อาร์กิวเมนต์อธิบายพารามิเตอร์ที่ส่งไปยังหน้าจอ — ชนิดและค่าเริ่มต้น

NavHostFragment คือคอนเทนเนอร์ที่วางในเลย์เอาต์ของ Activity และแสดงหน้าจอการนำทางปัจจุบัน NavHostFragment จะสลับแฟรกเมนต์โดยอัตโนมัติเมื่อเรียก NavController.navigate() NavController คือออบเจ็กต์ที่จัดการการนำทาง: การเปลี่ยนหน้า การย้อนกลับ และการตรวจสอบเส้นทางปัจจุบัน

kotlin
// Layout Activity: activity_main.xml
// <androidx.fragment.app.FragmentContainerView
//     android:id="@+id/nav_host_fragment"
//     android:name="androidx.navigation.fragment.NavHostFragment"
//     app:navGraph="@navigation/nav_graph"
//     app:defaultNavHost="true" />

class MainActivity : AppCompatActivity() {

    private val navController by lazy {
        (findViewById<NavHostFragment>(R.id.nav_host_fragment))
            .navController
    }

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

        // NavigationUI เชื่อมต่อ NavController กับ AppBar
        setupActionBarWithNavController(navController)
    }

    // นำทางไปยังหน้าจอรายละเอียด
    fun openDetail(itemId: Long) {
        val bundle = Bundle().apply {
            putLong("itemId", itemId)
        }
        navController.navigate(R.id.action_home_to_detail, bundle)
    }

    override fun onSupportNavigateUp() = 
        navController.navigateUp() || super.onSupportNavigateUp()
}

app:defaultNavHost="true" เป็นแอตทริบิวต์สำคัญ: มันสกัดกั้นปุ่มย้อนกลับของระบบและส่งต่อการควบคุมไปยัง NavController NavigationUI เป็นยูทิลิตี้สำหรับเชื่อมโยง NavController กับ AppBar, BottomNavigationView, NavigationDrawer setupActionBarWithNavController เปิดใช้งานลูกศรย้อนกลับบนหน้าจอที่ซ้อนกัน

Navigation Component รองรับแอนิเมชันการเปลี่ยนหน้าแบบกำหนดเอง ซึ่งตั้งค่าในการกระทำหรือโดยโปรแกรม แอนิเมชันถูกกำหนดโดยสี่แอตทริบิวต์: enterAnim (การปรากฏของหน้าจอใหม่), exitAnim (การหายไปของหน้าจอปัจจุบัน), popEnterAnim (การปรากฏเมื่อย้อนกลับ) และ popExitAnim (การหายไปเมื่อย้อนกลับ)

xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="100%"
        android:toXDelta="0%"
        android:duration="300" />
</set>

// การเปลี่ยนหน้าโดยโปรแกรมพร้อมแอนิเมชัน
val navOptions = NavOptions.Builder()
    .setEnterAnim(R.anim.slide_in_right)
    .setExitAnim(R.anim.slide_out_left)
    .setPopEnterAnim(R.anim.slide_in_left)
    .setPopExitAnim(R.anim.slide_out_right)
    .build()

navController.navigate(R.id.detailFragment, args, navOptions)

แอนิเมชันทำงานกับ Fragment ในระดับ FragmentTransaction สำหรับ Jetpack Compose แอนิเมชันถูกตั้งค่าผ่าน NavOptionsCompat โดยใช้ Compose Animation Navigation Component ไม่จำกัดชนิดของแอนิเมชัน — รองรับ translate, scale, alpha และการรวมกัน

Safe Args: อาร์กิวเมนต์ที่ปลอดภัยชนิด

Safe Args คือปลั๊กอิน Gradle สำหรับการถ่ายโอนข้อมูลที่ปลอดภัยชนิดระหว่างหน้าจอ ปลั๊กอินวิเคราะห์ NavGraph สร้างคลาส Directions และ Args พร้อมชนิดฟิลด์เฉพาะ การตรวจสอบชนิดเกิดขึ้นในเวลาคอมไพล์ — MissingArgumentException ถูกตรวจจับก่อนที่แอปจะทำงาน

kotlin
// build.gradle (module)
plugins {
    id 'androidx.navigation.safeargs.kotlin'
}

// Safe Args สร้าง: DetailFragmentArgs, HomeFragmentDirections
// การใช้งานใน HomeFragment:
val action = HomeFragmentDirections
    .actionHomeToDetail(itemId = 42L)
findNavController().navigate(action)

// การใช้งานใน DetailFragment:
private val args: DetailFragmentArgs by navArgs()
// args.itemId เป็นชนิด Long ไม่สามารถส่ง null ได้

override fun onViewCreated(...) {
    super.onViewCreated(...)
    loadItem(args.itemId)
}

navArgs() คือตัวแทน Kotlin สำหรับดึงอาร์กิวเมนต์ใน Fragment หรือ Activity ปลั๊กอินรองรับชนิดดั้งเดิม, สตริง, Parcelable, Serializable, Enum และอาร์เรย์ สำหรับออบเจ็กต์ที่ซับซ้อน ให้ส่ง ID และโหลดจาก ViewModel หรือฐานข้อมูล

Deep Link คือลิงก์ภายนอกที่เปิดหน้าจอเฉพาะของแอป Navigation Component จัดการลิงก์ลึกผ่านแอตทริบิวต์ app:deepLink ใน NavGraph ระบบสร้าง PendingIntent ที่คืนค่าสแตกการนำทางไปยังหน้าจอเป้าหมาย หรือสร้างสแตกใหม่หากแอปไม่ได้ทำงาน

xml

<fragment android:id="@+id/profileFragment"
    android:name=".ProfileFragment">
    <deepLink
        app:uri="https://example.com/profile/{userId}" />
    <argument
        android:name="userId"
        app:argType="string" />
</fragment>

// การสร้าง Deep Link โดยโปรแกรม
val pendingIntent = NavDeepLinkBuilder(context)
    .setGraph(R.navigation.nav_graph)
    .setDestination(R.id.profileFragment)
    .setArguments(Bundle().apply {
        putString("userId", "user_123")
    })
    .createPendingIntent()

ลิงก์ลึกรองรับรูปแบบ URI พร้อมพาธและพารามิเตอร์สอบถาม intent action และชนิด mime ตัวยึดตำแหน่ง ({userId}) จะถูกแมปกับอาร์กิวเมนต์ปลายทางโดยอัตโนมัติ Navigation Component ยังจัดการลิงก์ลึกโดยนัยผ่าน AndroidManifest — เพียงเพิ่ม intent-filter ให้กับ Activity ที่มี NavHostFragment

Navigation Compose (androidx.navigation:navigation-compose) คือส่วนขยายของ Navigation Component สำหรับ Jetpack Compose API ยังคงแนวคิดของ NavController และ NavHost แต่หน้าจอเป็นฟังก์ชัน Composable แทน Fragment NavHost รับ lambda composable สำหรับแต่ละเส้นทาง

kotlin
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyAppTheme {
                val navController = rememberNavController()
                NavHost(
                    navController = navController,
                    startDestination = "home"
                ) {
                    composable("home") {
                        HomeScreen(
                            onItemClick = { id ->
                                navController.navigate("detail/$id")
                            }
                        )
                    }
                    composable(
                        route = "detail/{itemId}",
                        arguments = listOf(
                            navArgument("itemId") {
                                type = NavType.LongType
                            }
                        )
                    ) { backStackEntry ->
                        val itemId = backStackEntry
                            .arguments?.getLong("itemId") ?: 0L
                        DetailScreen(itemId = itemId)
                    }
                }
            }
        }
    }
}

Navigation Compose ใช้เส้นทางสตริงแทน id พารามิเตอร์ถูกส่งผ่านเทมเพลตเส้นทาง ("detail/{itemId}") และดึงจาก backStackEntry rememberNavController() รักษา NavController ระหว่างการประกอบซ้ำ สำหรับความปลอดภัยชนิดใน Compose โมดูล navigation-compose-type-safety (ทดลอง) ได้รับคำแนะนำ

คำถามที่พบบ่อย

NavHost ใน Navigation Component คืออะไร?

NavHost คือคอนเทนเนอร์สำหรับแสดงหน้าจอการนำทาง มันถูกใช้งานผ่าน NavHostFragment ในเลย์เอาต์ XML NavHost ติดตามหน้าจอปัจจุบันใน NavGraph และจัดการการเปลี่ยนหน้า แต่ละ Activity มี NavHostFragment หนึ่งตัว

Safe Args ดีกว่า Bundle อย่างไร?

Safe Args คือปลั๊กอิน Gradle ที่สร้างคลาสอาร์กิวเมนต์ที่ปลอดภัยชนิด Bundle ต้องการการระบุคีย์และชนิดด้วยตนเอง ซึ่งนำไปสู่ข้อผิดพลาดขณะทำงาน Safe Args ตรวจสอบชนิดในเวลาคอมไพล์และทำให้ข้อมูลเป็นอนุกรมโดยอัตโนมัติ

จะส่งออบเจ็กต์ที่ซับซ้อนผ่าน Navigation Component ได้อย่างไร?

ออบเจ็กต์ที่ซับซ้อนถูกส่งผ่าน ViewModel (ใช้ร่วมกันระหว่างหน้าจอ) หรือผ่านฐานข้อมูลโดยส่ง ID Safe Args รองรับเฉพาะชนิดดั้งเดิม สตริง และ Parcelable Google แนะนำให้หลีกเลี่ยงการส่งออบเจ็กต์ขนาดใหญ่ผ่านอาร์กิวเมนต์การนำทาง

Deep Link ใน Navigation Component ทำงานอย่างไร?

Deep Link ถูกกำหนดค่าใน NavGraph ผ่านแอตทริบิวต์ app:deepLink Navigation Component จัดการลิงก์ขาเข้าโดยอัตโนมัติ สร้าง PendingIntent ผ่าน NavDeepLinkBuilder และคืนค่าสแตกการนำทางไปยังหน้าจอเป้าหมาย รองรับ URI, intent action และชนิด mime

สามารถใช้ Navigation Component กับ Jetpack Compose ได้หรือไม่?

ได้ Navigation Compose (androidx.navigation:navigation-compose) มี NavHost สำหรับ Compose API คล้ายกับเวอร์ชัน XML แต่หน้าจอเป็นฟังก์ชัน Composable NavController ถูกใช้เหมือนกันในทั้งสองเวอร์ชัน Google แนะนำ Navigation Compose สำหรับโปรเจกต์ Compose ใหม่

สรุป

  • Navigation Component — ไลบรารี Android Jetpack สำหรับการนำทางแบบรวมศูนย์ด้วย NavController, NavHost และ NavGraph
  • NavGraph — กราฟ XML ที่อธิบายหน้าจอทั้งหมด (ปลายทาง) และการเชื่อมต่อ (การกระทำ) ระหว่างกัน
  • NavHostFragment — คอนเทนเนอร์ในเลย์เอาต์ของ Activity ที่รองรับแอตทริบิวต์ defaultNavHost สำหรับปุ่มย้อนกลับ
  • Safe Args — ปลั๊กอิน Gradle สำหรับการส่งผ่านอาร์กิวเมนต์ที่ปลอดภัยชนิดพร้อมการตรวจสอบชนิดในเวลาคอมไพล์
  • ลิงก์ลึก รองรับ URI, intent action และชนิด mime พร้อมการคืนค่าสแตกการนำทางอัตโนมัติ
  • Navigation Compose — ส่วนขยายสำหรับ Jetpack Compose พร้อมเส้นทางสตริงและหน้าจอ composable
  • Navigation Component เป็นวิธีนำทางเดียวที่ Google แนะนำสำหรับโปรเจกต์ Android ใหม่

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม