Mem-build navigasi adaptif

Sebagian besar aplikasi memiliki beberapa tujuan tingkat teratas yang dapat diakses melalui UI navigasi utama aplikasi. Di jendela yang rapat, seperti layar ponsel standar, tujuan biasanya ditampilkan di menu navigasi di bagian bawah jendela. Di jendela yang diperluas, seperti aplikasi layar penuh di tablet, kolom samping navigasi di samping aplikasi biasanya merupakan pilihan yang lebih baik karena kontrol navigasi lebih mudah dijangkau saat memegang sisi kiri dan kanan perangkat.

NavigationSuiteScaffold menyederhanakan peralihan antara UI navigasi dengan menampilkan composable UI navigasi yang sesuai berdasarkan WindowSizeClass. Hal ini termasuk mengubah UI secara dinamis selama perubahan ukuran jendela runtime. Perilaku defaultnya adalah menampilkan salah satu komponen UI berikut:

  • Menu navigasi jika lebar atau tinggi perangkat ringkas atau jika perangkat dalam postur di atas meja
  • Kolom samping navigasi untuk hal lainnya
Gambar 1. NavigationSuiteScaffold menampilkan menu navigasi di jendela rapat.
Gambar 2. NavigationSuiteScaffold menampilkan kolom samping navigasi di jendela yang diperluas.

Menambahkan dependensi

NavigationSuiteScaffold adalah bagian dari library paket navigasi adaptif Material3. Tambahkan dependensi untuk library dalam file build.gradle aplikasi atau modul Anda:

Kotlin

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

Groovy

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

Membuat scaffold

Dua bagian utama NavigationSuiteScaffold adalah item suite navigasi dan konten untuk tujuan yang dipilih. Anda dapat langsung menentukan item suite navigasi dalam composable, tetapi biasanya item ini ditentukan di tempat lain, misalnya, dalam 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),
}

Untuk menggunakan NavigationSuiteScaffold, Anda harus melacak tujuan saat ini, yang dapat Anda lakukan menggunakan rememberSaveable:

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

Dalam contoh berikut, parameter navigationSuiteItems (jenis NavigationSuiteScope) menggunakan fungsi item-nya untuk menentukan UI navigasi untuk setiap tujuan. UI tujuan digunakan di seluruh menu navigasi, kolom samping, dan panel samping. Untuk membuat item navigasi, Anda melakukan loop pada AppDestinations (ditentukan dalam cuplikan sebelumnya):

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.
}

Dalam lambda konten tujuan, gunakan nilai currentDestination untuk memutuskan UI yang akan ditampilkan. Jika Anda menggunakan library navigasi di aplikasi, gunakan library tersebut di sini untuk menampilkan tujuan yang sesuai. Pernyataan when sudah cukup:

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

Ubah warna

NavigationSuiteScaffold membuat Surface di seluruh area yang ditempati scaffold, biasanya jendela penuh. Selain itu, scaffold menggambar UI navigasi tertentu, seperti NavigationBar. Platform dan UI navigasi menggunakan nilai yang ditentukan dalam tema aplikasi, tetapi Anda dapat mengganti nilai tema.

Parameter containerColor menentukan warna permukaan. Defaultnya adalah warna latar belakang skema warna Anda. Parameter contentColor menentukan warna konten di permukaan tersebut. Defaultnya adalah warna "on" dari apa pun yang ditentukan untuk containerColor. Misalnya, jika containerColor menggunakan warna background, contentColor akan menggunakan warna onBackground. Lihat Tema Desain Material 3 di Compose untuk mengetahui detail selengkapnya tentang cara kerja sistem warna. Saat mengganti nilai ini, gunakan nilai yang ditentukan dalam tema Anda agar aplikasi mendukung mode tampilan gelap dan terang:

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

UI navigasi digambar di depan platform NavigationSuiteScaffold. Nilai default untuk warna UI disediakan oleh NavigationSuiteDefaults.colors(), tetapi Anda juga dapat mengganti nilai ini. Misalnya, jika Anda ingin latar belakang menu navigasi menjadi transparan, tetapi nilai lainnya menjadi default, ganti navigationBarContainerColor:

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

Terakhir, Anda dapat menyesuaikan setiap item di UI navigasi. Saat memanggil fungsi item, Anda dapat meneruskan instance NavigationSuiteItemColors. Class ini menentukan warna untuk item di menu navigasi, kolom samping navigasi, dan panel samping navigasi. Artinya, Anda dapat memiliki warna yang sama di setiap jenis UI navigasi, atau Anda dapat memvariasikan warna berdasarkan kebutuhan Anda. Tentukan warna di tingkat NavigationSuiteScaffold untuk menggunakan instance objek yang sama untuk semua item dan panggil fungsi NavigationSuiteDefaults.itemColors() untuk mengganti hanya warna yang ingin Anda ubah:

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...
}

Menyesuaikan jenis navigasi

Perilaku default NavigationSuiteScaffold mengubah UI navigasi berdasarkan class ukuran jendela. Namun, Anda mungkin ingin mengganti perilaku ini. Misalnya, jika aplikasi Anda menampilkan satu panel konten besar untuk feed, aplikasi dapat menggunakan panel navigasi permanen untuk jendela yang diperluas, tetapi tetap menggunakan perilaku default untuk class ukuran jendela rapat dan sedang:

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...
}

Referensi lainnya