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

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

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

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

เพิ่มการพึ่งพา

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 ส่วนหลักๆ ได้แก่ รายการชุดการนำทางและเนื้อหาสำหรับปลายทางที่เลือก คุณสามารถกําหนดรายการชุดการนําทางในคอมโพสิเบิลได้โดยตรง แต่โดยทั่วไปแล้วจะมีการกําหนดรายการเหล่านี้ไว้ที่อื่น เช่น ใน 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 (ประเภท 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 ทั่วทั้งพื้นที่ที่นั่งร้านครอบครอง ซึ่งโดยทั่วไปคือทั้งหน้าต่าง นอกจากนี้ เฟรมเวิร์กยังวาด 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 NavigationSuiteDefaults.colors() จะระบุค่าเริ่มต้นสำหรับสี UI แต่คุณลบล้างค่าเหล่านี้ได้ด้วย ตัวอย่างเช่น หากต้องการให้พื้นหลังของแถบนำทางโปร่งใส แต่ค่าอื่นๆ เป็นค่าเริ่มต้น ให้ลบล้าง 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.windowWidthSizeClass == WindowWidthSizeClass.EXPANDED) {
        NavigationSuiteType.NavigationDrawer
    } else {
        NavigationSuiteScaffoldDefaults.calculateFromAdaptiveInfo(adaptiveInfo)
    }
}

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

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