สร้างการนำทางแบบปรับอัตโนมัติ

แอปส่วนใหญ่มีปลายทางระดับบนสุด 2-3 แห่งที่เข้าถึงได้ผ่าน UI การนำทางหลักของแอป ในหน้าต่างขนาดกะทัดรัด เช่น จอแสดงผลของโทรศัพท์มาตรฐาน ปลายทางมักจะแสดงในแถบนำทางที่ด้านล่างของหน้าต่าง ในหน้าต่างที่ขยาย เช่น แอปแบบเต็มหน้าจอบนแท็บเล็ต แถบนำทางข้างแอปมักจะเป็นตัวเลือกที่ดีกว่า เนื่องจากควบคุมการนำทางได้ง่ายกว่าขณะถืออุปกรณ์ด้านซ้ายและขวา

NavigationSuiteScaffold ช่วยให้การสลับ ระหว่าง UI การนำทางง่ายขึ้นโดยแสดง Composable ของ UI การนำทางที่เหมาะสม ตาม WindowSizeClass ซึ่งรวมถึงการเปลี่ยน UI แบบไดนามิกระหว่างการเปลี่ยนแปลงขนาดหน้าต่างขณะรันไทม์ ลักษณะการทำงานเริ่มต้นคือการ แสดงคอมโพเนนต์ UI อย่างใดอย่างหนึ่งต่อไปนี้

  • แถบนำทางหากความกว้างหรือความสูงมีขนาดกะทัดรัด หรือหากอุปกรณ์อยู่ใน ท่าทางบนโต๊ะ
  • แถบข้างสำหรับไปยังส่วนต่างๆ สำหรับทุกอย่างอื่นๆ
รูปที่ 1 NavigationSuiteScaffold จะแสดงแถบนำทางในหน้าต่างขนาดกะทัดรัด
รูปที่ 2 NavigationSuiteScaffold จะแสดงแถบข้างสำหรับไปยังส่วนต่างๆ ในหน้าต่างที่ขยาย

เพิ่มทรัพยากร Dependency

NavigationSuiteScaffold เป็นส่วนหนึ่งของไลบรารีชุดการนำทางแบบปรับได้ Material3 เพิ่มทรัพยากร Dependency สำหรับไลบรารีในไฟล์ build.gradle ของแอป หรือโมดูล

Kotlin

implementation("androidx.compose.material3:material3-adaptive-navigation-suite")

Groovy

implementation 'androidx.compose.material3:material3-adaptive-navigation-suite'

สร้างโครงร่าง

NavigationSuiteScaffold มี 2 ส่วนหลักๆ คือรายการชุดการนำทาง และเนื้อหาสำหรับปลายทางที่เลือก คุณสามารถกำหนดรายการชุดการนำทางใน Composable ได้โดยตรง แต่โดยทั่วไปแล้วจะกำหนดรายการเหล่านี้ไว้ที่อื่น เช่น ใน Enum

enum class AppDestinations(
    @StringRes val label: Int,
    val icon: ImageVector,
    @StringRes val contentDescription: Int
) {
    HOME(R.string.home, Icons.Default.Home, R.string.home),
    FAVORITES(R.string.favorites, Icons.Default.Favorite, R.string.favorites),
    SHOPPING(R.string.shopping, Icons.Default.ShoppingCart, R.string.shopping),
    PROFILE(R.string.profile, Icons.Default.AccountBox, R.string.profile),
}

หากต้องการใช้ NavigationSuiteScaffold คุณต้องติดตามปลายทางปัจจุบัน ซึ่งทำได้โดยใช้ rememberSaveable ดังนี้

var currentDestination by rememberSaveable { mutableStateOf(AppDestinations.HOME) }

ในตัวอย่างต่อไปนี้ พารามิเตอร์ navigationSuiteItems (type NavigationSuiteScope) ใช้ฟังก์ชัน item เพื่อกำหนด UI การนำทางสำหรับปลายทางแต่ละแห่ง UI ปลายทางจะ ใช้ในแถบนำทาง แถบด้านข้าง และลิ้นชัก หากต้องการสร้างรายการนำทาง ให้วนซ้ำ AppDestinations (กำหนดไว้ในข้อมูลโค้ดก่อนหน้า) ดังนี้

NavigationSuiteScaffold(
    navigationSuiteItems = {
        AppDestinations.entries.forEach {
            item(
                icon = {
                    Icon(
                        it.icon,
                        contentDescription = stringResource(it.contentDescription)
                    )
                },
                label = { Text(stringResource(it.label)) },
                selected = it == currentDestination,
                onClick = { currentDestination = it }
            )
        }
    }
) {
    // TODO: Destination content.
}

ภายใน Lambda ของเนื้อหาปลายทาง ให้ใช้ค่า currentDestination เพื่อ ตัดสินใจว่าจะแสดง UI ใด หากใช้ไลบรารีการนำทางในแอป ให้ใช้ไลบรารีที่นี่เพื่อแสดงปลายทางที่เหมาะสม คุณใช้คำสั่ง when ได้ดังนี้

NavigationSuiteScaffold(
    navigationSuiteItems = { /*...*/ }
) {
    // Destination content.
    when (currentDestination) {
        AppDestinations.HOME -> HomeDestination()
        AppDestinations.FAVORITES -> FavoritesDestination()
        AppDestinations.SHOPPING -> ShoppingDestination()
        AppDestinations.PROFILE -> ProfileDestination()
    }
}

เปลี่ยนสี

NavigationSuiteScaffold สร้าง Surface ทั่วทั้งพื้นที่ ที่โครงสร้างครอบครอง ซึ่งโดยทั่วไปคือทั้งหน้าต่าง นอกจากนี้ Scaffold ยังวาด UI การนำทางที่เฉพาะเจาะจง เช่น NavigationBar ทั้ง UI ของพื้นผิวและ UI ของการนำทางใช้ค่าที่ระบุไว้ในธีมของแอป แต่คุณสามารถลบล้างค่าธีมได้

พารามิเตอร์ containerColor ระบุสีของพื้นผิว ค่าเริ่มต้น คือสีพื้นหลังของรูปแบบสี พารามิเตอร์ contentColor ระบุสีของเนื้อหาในแพลตฟอร์มนั้น ค่าเริ่มต้นคือสี "เปิด" ของค่าที่ระบุสำหรับ containerColor เช่น หาก containerColor ใช้สี background contentColor จะใช้สี onBackground ดูรายละเอียดเพิ่มเติมเกี่ยวกับวิธีการทำงานของระบบสีได้ที่การกำหนดธีม Material Design 3 ใน Compose เมื่อลบล้างค่าเหล่านี้ ให้ ใช้ค่าที่กำหนดไว้ในธีมเพื่อให้แอปของคุณรองรับโหมด การแสดงผลแบบมืดและสว่าง

NavigationSuiteScaffold(
    navigationSuiteItems = { /* ... */ },
    containerColor = MaterialTheme.colorScheme.primary,
    contentColor = MaterialTheme.colorScheme.onPrimary,
) {
    // Content...
}

ระบบจะวาด UI การนำทางไว้ด้านหน้าพื้นผิว NavigationSuiteScaffold ค่าเริ่มต้นสำหรับสี UI มาจาก NavigationSuiteDefaults.colors() แต่คุณก็ ลบล้างค่าเหล่านี้ได้เช่นกัน ตัวอย่างเช่น หากต้องการให้พื้นหลังของแถบนำทางโปร่งใส แต่ให้ค่าอื่นๆ เป็นค่าเริ่มต้น ให้ลบล้าง navigationBarContainerColor:

NavigationSuiteScaffold(
    navigationSuiteItems = { /* ... */ },
    navigationSuiteColors = NavigationSuiteDefaults.colors(
        navigationBarContainerColor = Color.Transparent,
    )
) {
    // Content...
}

ท้ายที่สุด คุณจะปรับแต่งแต่ละรายการใน UI การนำทางได้ เมื่อเรียกใช้ฟังก์ชัน item คุณจะส่งอินสแตนซ์ของ NavigationSuiteItemColorsได้ คลาสนี้ระบุ สีสำหรับรายการในแถบนำทาง แถบนำทาง และ ลิ้นชักการนำทาง ซึ่งหมายความว่าคุณสามารถใช้สีเดียวกันใน UI การนำทางแต่ละประเภท หรือจะใช้สีที่แตกต่างกันตามความต้องการก็ได้ กำหนดสีที่ระดับ NavigationSuiteScaffold เพื่อใช้ออบเจ็กต์อินสแตนซ์เดียวกันสำหรับสินค้าทั้งหมด และเรียกใช้ฟังก์ชัน NavigationSuiteDefaults.itemColors() เพื่อลบล้างเฉพาะ รายการที่คุณต้องการเปลี่ยน

val myNavigationSuiteItemColors = NavigationSuiteDefaults.itemColors(
    navigationBarItemColors = NavigationBarItemDefaults.colors(
        indicatorColor = MaterialTheme.colorScheme.primaryContainer,
        selectedIconColor = MaterialTheme.colorScheme.onPrimaryContainer
    ),
)

NavigationSuiteScaffold(
    navigationSuiteItems = {
        AppDestinations.entries.forEach {
            item(
                icon = {
                    Icon(
                        it.icon,
                        contentDescription = stringResource(it.contentDescription)
                    )
                },
                label = { Text(stringResource(it.label)) },
                selected = it == currentDestination,
                onClick = { currentDestination = it },
                colors = myNavigationSuiteItemColors,
            )
        }
    },
) {
    // Content...
}

ปรับแต่งประเภทการนำทาง

ลักษณะการทำงานเริ่มต้นของ NavigationSuiteScaffold จะเปลี่ยน UI การนำทาง โดยอิงตามคลาสขนาดหน้าต่าง อย่างไรก็ตาม คุณอาจต้องการลบล้างลักษณะการทำงานนี้ ตัวอย่างเช่น หากแอปแสดงเนื้อหาบานหน้าต่างขนาดใหญ่รายการเดียวสำหรับฟีด แอปอาจใช้แถบนำทางถาวรสำหรับหน้าต่างที่ขยาย แต่ยังคงกลับไปใช้ลักษณะการทำงานเริ่มต้นสำหรับคลาสขนาดหน้าต่างแบบกะทัดรัดและขนาดกลาง

val adaptiveInfo = currentWindowAdaptiveInfo()
val customNavSuiteType = with(adaptiveInfo) {
    if (windowSizeClass.isWidthAtLeastBreakpoint(WIDTH_DP_EXPANDED_LOWER_BOUND)) {
        NavigationSuiteType.NavigationDrawer
    } else {
        NavigationSuiteScaffoldDefaults.calculateFromAdaptiveInfo(adaptiveInfo)
    }
}

NavigationSuiteScaffold(
    navigationSuiteItems = { /* ... */ },
    layoutType = customNavSuiteType,
) {
    // Content...
}

แหล่งข้อมูลเพิ่มเติม