Material 3 Expressive adalah evolusi berikutnya dari Desain Material. Desain ini mencakup tema, komponen, dan fitur personalisasi yang diperbarui seperti warna dinamis.
Panduan ini berfokus pada migrasi dari library Jetpack Wear Compose Material 2.5 (androidx.wear.compose) ke library Jetpack Wear Compose Material 3 (androidx.wear.compose.material3) untuk aplikasi.
Pendekatan
Untuk memigrasikan kode aplikasi dari M2.5 ke M3, ikuti pendekatan yang sama seperti yang dijelaskan dalam panduan ponsel migrasi Material Compose, khususnya:
- Anda tidak boleh menggunakan M2.5 dan M3 dalam satu aplikasi jangka panjang.
- Menggunakan pendekatan bertahap
Dependensi
M3 memiliki paket dan versi terpisah untuk M2.5:
M2.5
implementation("androidx.wear.compose:compose-material:1.4.0")
M3
implementation("androidx.wear.compose:compose-material3:1.6.0-alpha04")
Lihat versi M3 terbaru di halaman rilis Wear Compose Material 3.
Library Wear Compose Foundation versi 1.6.0-alpha04 memperkenalkan beberapa komponen baru yang didesain untuk bekerja dengan komponen Material 3.
Demikian pula, SwipeDismissableNavHost dari library Wear Compose Navigation memiliki
animasi yang diperbarui saat dijalankan di Wear OS 6 (level API 36) atau yang lebih tinggi. Saat
mengupdate ke Wear Compose Material 3, sebaiknya update juga library Wear
Compose Foundation dan Navigation:
implementation("androidx.wear.compose:compose-foundation:1.6.0-alpha04")
implementation("androidx.wear.compose:compose-navigation:1.6.0-alpha04")
Tema
Pada M2.5 dan M3, composable tema diberi nama MaterialTheme, tetapi
paket dan parameter impornya berbeda. Di M3, parameter Colors telah
diganti namanya menjadi ColorScheme dan MotionScheme telah diperkenalkan untuk menerapkan
transisi.
M2.5
import androidx.wear.compose.material.MaterialTheme
MaterialTheme(
colors = AppColors,
typography = AppTypography,
shapes = AppShapes,
content = content
)
M3
import androidx.wear.compose.material3.MaterialTheme
MaterialTheme(
colorScheme = AppColorScheme,
typography = AppTypography,
shapes = AppShapes,
motionScheme = AppMotionScheme,
content = content
)
Warna
Sistem warna di M3 sangat berbeda dengan M2.5. Jumlah parameter warna
telah meningkat, memiliki nama berbeda, dan dipetakan berbeda ke
komponen M3. Di Compose, ini berlaku untuk class Colors M2.5, class
ColorScheme M3, dan fungsi terkait:
M2.5
import androidx.wear.compose.material.Colors
val appColorScheme: Colors = Colors(
// M2.5 Color parameters
)
M3
import androidx.wear.compose.material3.ColorScheme
val appColorScheme: ColorScheme = ColorScheme(
// M3 ColorScheme parameters
)
Tabel berikut menjelaskan perbedaan utama antara M2.5 dan M3:
M2.5 |
M3 |
|---|---|
|
telah diganti namanya menjadi |
13 Warna |
28 Warna |
T/A |
tema warna dinamis baru |
T/A |
warna tersier baru untuk ekspresi yang lebih banyak |
Tema Warna Dinamis
Fitur baru di M3 adalah tema warna dinamis. Jika pengguna mengubah warna tampilan jam, warna di UI akan berubah agar cocok.
Gunakan fungsi dynamicColorScheme untuk menerapkan skema warna dinamis
dan menyediakan defaultColorScheme sebagai penggantian jika skema warna dinamis
tidak tersedia.
@Composable
fun myApp() {
val myColorScheme = myBrandColors()
val dynamicColorScheme = dynamicColorScheme(LocalContext.current)
MaterialTheme(colorScheme = dynamicColorScheme ?: myBrandColors) {...}
}
Tipografi
Sistem tipografi di M3 berbeda dengan M2 dan mencakup fitur berikut:
- Sembilan gaya teks baru
- Font fleksibel, yang memungkinkan penyesuaian skala huruf untuk berbagai ketebalan, lebar, dan kebulatan
AnimatedText, yang menggunakan font fleksibel
M2.5
import androidx.wear.compose.material.Typography
val Typography = Typography(
// M2.5 TextStyle parameters
)
M3
import androidx.wear.compose.material3.Typography
val Typography = Typography(
// M3 TextStyle parameters
)
Font Fleksibel
Dengan Font Fleksibel, desainer dapat menentukan lebar dan ketebalan huruf untuk ukuran tertentu.
Gaya Teks
TextStyle berikut tersedia di M3. Warna ini digunakan secara default oleh berbagai komponen M3.
Tipografi |
TextStyle |
|---|---|
Tampilan |
displayLarge, displayMedium, displaySmall |
Judul |
titleLarge, titleMedium, titleSmall |
Label |
labelLarge, labelMedium, labelSmall |
Isi |
bodyLarge, bodyMedium, bodySmall, bodyExtraSmall |
Angka |
numeralExtraLarge, numeralLarge, numeralMedium, numeralSmall, numeralExtraSmall |
Busur |
arcLarge, arcMedium, arcSmall |
Bentuk
Sistem bentuk di M3 berbeda dengan M2. Jumlah parameter bentuk telah meningkat, diberi nama berbeda, dan dipetakan berbeda ke komponen M3. Ukuran bentuk berikut tersedia:
- Ekstra kecil
- Kecil
- Sedang
- Besar
- Ekstra besar
Di Compose, ini berlaku untuk class Shapes M2 dan class
Shapes M3:
M2.5
import androidx.wear.compose.material.Shapes
val Shapes = Shapes(
// M2.5 Shapes parameters
)
M3
import androidx.wear.compose.material3.Shapes
val Shapes = Shapes(
// M3 Shapes parameters
)
Gunakan pemetaan parameter Bentuk dari Bermigrasi dari Material 2 ke Material 3 di Compose sebagai titik awal.
Perubahan bentuk
M3 memperkenalkan Shape Morphing: bentuk kini berubah sebagai respons terhadap interaksi.
Perilaku Perubahan Bentuk tersedia sebagai variasi pada sejumlah tombol bulat, lihat daftar tombol berikut yang mendukung Perubahan Bentuk:
Tombol |
Fungsi perubahan bentuk |
|---|---|
|
IconButtonDefaults.animatedShape() menganimasikan tombol ikon saat ditekan |
|
IconToggleButtonDefaults.animatedShape() menganimasikan tombol pengalihan ikon saat ditekan dan IconToggleButtonDefaults.variantAnimatedShapes() menganimasikan tombol toggle ikon saat ditekan dan dicentang/dihapus centangnya |
|
TextButtonDefaults.animatedShape() menganimasikan tombol teks saat ditekan |
|
TextToggleButtonDefaults.animatedShapes() menganimasikan tombol teks saat ditekan dan TextToggleButtonDefaults.variantAnimatedShapes() menganimasikan tombol teks saat ditekan dan dicentang/dihapus centangnya |
Komponen dan Tata Letak
Sebagian besar komponen dan tata letak dari M2.5 tersedia di M3. Namun, beberapa komponen dan tata letak M3 tidak ada di M2.5. Selain itu, beberapa komponen M3 memiliki lebih banyak variasi dibandingkan dengan yang setara di M2.5.
Meskipun beberapa komponen memerlukan pertimbangan khusus, pemetaan fungsi berikut direkomendasikan sebagai titik awal:
Berikut daftar lengkap semua komponen Material 3:
Material 3 |
Komponen yang setara dengan Material 2.5 (jika tidak baru di M3) |
|---|---|
Baru |
|
Baru |
|
android.wear.compose.material.Scaffold (dengan androidx.wear.compose.material3.ScreenScaffold ) |
|
Baru |
|
androidx.wear.compose.material.ToggleChip dengan kontrol tombol kotak centang |
|
androidx.wear.compose.material.Chip (hanya jika tidak diperlukan latar belakang) |
|
Baru |
|
Baru |
|
Baru |
|
androidx.wear.compose.material.Chip saat latar belakang tombol tonal diperlukan |
|
Baru |
|
Baru |
|
Baru |
|
Baru |
|
Baru |
|
androidx.wear.compose.material.ToggleChip dengan kontrol tombol pilihan |
|
android.wear.compose.material.Scaffold (dengan androidx.wear.compose material3.AppScaffold) |
|
androidx.wear.compose.material3.SegmentedCircularProgressIndicator |
Baru |
androidx.wear.compose.material.SwipeToRevealCard dan androidx.wear.compose.material.SwipeToRevealChip |
|
androidx.wear.compose.material.ToggleChip dengan kontrol tombol pengaktifan |
|
Baru |
Terakhir, daftar beberapa komponen yang relevan dari library Wear Compose Foundation, yang pertama kali diperkenalkan dalam versi 1.6.0-alpha04:
Wear Compose Foundation 1.6.0-alpha04 |
|
|---|---|
Digunakan untuk menganotasi composable dalam aplikasi, untuk melacak bagian komposisi yang aktif dan mengoordinasikan fokus. |
|
Pager yang dapat di-scroll secara horizontal, dibangun berdasarkan komponen Compose Foundation dengan peningkatan khusus Wear untuk meningkatkan performa dan kepatuhan terhadap panduan Wear OS. |
|
Pager yang dapat di-scroll secara vertikal, dibangun di komponen Compose Foundation dengan peningkatan khusus Wear untuk meningkatkan performa dan kepatuhan terhadap panduan Wear OS. |
|
Dapat digunakan sebagai pengganti |
|
Tombol
Tombol di M3 berbeda dengan M2.5. Chip M2.5 telah digantikan oleh
Button. Implementasi Button memberikan nilai default untuk Text
maxLines dan textAlign. Nilai default tersebut dapat diganti dalam elemen Text.
M2.5
import androidx.wear.compose.material.Chip
//M2.5 Buttons
Chip(...)
CompactChip(...)
Button(...)
M3
import androidx.wear.compose.material3.Button
//M3 Buttons
Button(...)
CompactButton(...)
IconButton(...)
TextButton(...)
M3 juga menyertakan variasi tombol baru. Lihat di ringkasan Referensi API Compose Material 3.
M3 memperkenalkan tombol baru: EdgeButton. EdgeButton tersedia dalam 4 ukuran berbeda: ekstra kecil, kecil, sedang, dan besar. Implementasi EdgeButton
memberikan nilai default untuk maxLines bergantung pada ukuran
yang dapat disesuaikan.
Jika Anda menggunakan TransformingLazyColumn dan ScalingLazyColumn, teruskan
EdgeButton ke ScreenScaffold sehingga EdgeButton berubah bentuk
saat men-scroll. Lihat kode berikut untuk memeriksa cara menggunakan EdgeButton dengan
ScreenScaffold dan TransformingLazyColumn.
import androidx.wear.compose.material3.EdgeButton
import androidx.wear.compose.material3.ScreenScaffold
ScreenScaffold(
scrollState = state,
contentPadding = contentPadding,
edgeButton = {
EdgeButton(...)
}
){ contentPadding ->
TransformingLazyColumn(state = state, contentPadding = contentPadding,){
// additional code here
}
}
Scaffold
Scaffold di M3 berbeda dengan M2.5. Di M3, AppScaffold dan composable
ScreenScaffold baru telah menggantikan Scaffold. AppScaffold dan
ScreenScaffold menata struktur layar dan mengoordinasikan transisi
komponen ScrollIndicator dan TimeText.
AppScaffold memungkinkan elemen layar statis seperti TimeText tetap terlihat
selama transisi dalam aplikasi seperti geser untuk menutup. Komponen ini menyediakan slot untuk
konten aplikasi utama, yang biasanya akan disediakan oleh komponen
navigasi seperti SwipeDismissableNavHost
Anda mendeklarasikan satu AppScaffold untuk Aktivitas dan menggunakan ScreenScaffold untuk setiap
Layar.
M2.5
import androidx.wear.compose.material.Scaffold
Scaffold {...}
M3
AppScaffold { val navController = rememberSwipeDismissableNavController() SwipeDismissableNavHost( navController = navController, startDestination = "message_list" ) { composable("message_list") { MessageList(onMessageClick = { id -> navController.navigate("message_detail/$id") }) } composable("message_detail/{id}") { MessageDetail(id = it.arguments?.getString("id")!!) } } } } // Implementation of one of the screens in the navigation @Composable fun MessageDetail(id: String) { // .. Screen level content goes here val scrollState = rememberTransformingLazyColumnState() val padding = rememberResponsiveColumnPadding( first = ColumnItemType.BodyText ) ScreenScaffold( scrollState = scrollState, contentPadding = padding ) { scaffoldPaddingValues -> // Screen content goes here // ...
Jika Anda menggunakan HorizontalPager dengan HorizontalPagerIndicator, Anda
dapat bermigrasi ke HorizontalPagerScaffold. HorizontalPagerScaffold ditempatkan dalam AppScaffold. AppScaffold dan HorizontalPagerScaffold menata struktur Pager dan mengoordinasikan transisi komponen HorizontalPageIndicator dan TimeText.
HorizontalPagerScaffold menampilkan HorizontalPageIndicator di bagian tengah layar secara default dan mengoordinasikan penayangan dan penyembunyian TimeText dan HorizontalPageIndicator sesuai dengan apakah Pager sedang di-paging atau tidak, yang ditentukan oleh PagerState.
Ada juga komponen AnimatedPage baru, yang menganimasikan halaman dalam
Pager dengan efek penskalaan dan scrim berdasarkan posisinya.
AppScaffold { val pagerState = rememberPagerState(pageCount = { 10 }) val columnState = rememberTransformingLazyColumnState() val contentPadding = rememberResponsiveColumnPadding( first = ColumnItemType.ListHeader, last = ColumnItemType.BodyText, ) HorizontalPagerScaffold(pagerState = pagerState) { HorizontalPager( state = pagerState, ) { page -> AnimatedPage(pageIndex = page, pagerState = pagerState) { ScreenScaffold( scrollState = columnState, contentPadding = contentPadding ) { contentPadding -> TransformingLazyColumn( state = columnState, contentPadding = contentPadding ) { item { ListHeader( modifier = Modifier.fillMaxWidth() ) { Text(text = "Pager sample") } } item { if (page == 0) { Text(text = "Page #$page. Swipe right") } else{ Text(text = "Page #$page. Swipe left and right") } } } } } } } }
Terakhir, M3 memperkenalkan VerticalPagerScaffold yang mengikuti
pola yang sama dengan HorizontalPagerScaffold:
import androidx.wear.compose.material3.AppScaffold
import androidx.wear.compose.material3.HorizontalPagerScaffold
import androidx.wear.compose.material3.ScreenScaffold
import androidx.wear.compose.foundation.pager.VerticalPager
import androidx.wear.compose.foundation.pager.rememberPagerState
AppScaffold {
val pagerState = rememberPagerState(pageCount = { 10 })
VerticalPagerScaffold(pagerState = pagerState) {
VerticalPager(
state = pagerState
) { page ->
AnimatedPage(pageIndex = page, pagerState = pagerState){
ScreenScaffold {
…
}
}
Placeholder
Ada beberapa perubahan API antara M2.5 dan M3.
Placeholder.PlaceholderDefaults kini menyediakan dua pengubah:
Modifier.placeholder, yang digambar sebagai pengganti konten yang belum dimuat- Efek berkilau placeholder
Modifier.placeholderShimmeryang memberikan efek berkilau placeholder yang berjalan dalam loop animasi saat menunggu data dimuat.
Lihat tabel berikut untuk mengetahui perubahan tambahan pada komponen Placeholder.
M2.5 |
M3 |
|---|---|
|
Telah dihapus |
|
Telah dihapus |
|
Telah diganti namanya menjadi |
|
Telah dihapus |
|
telah dihapus |
|
Telah dihapus |
|
Telah dihapus |
SwipeDismissableNavHost
SwipeDismissableNavHost adalah bagian dari wear.compose.navigation. Saat komponen ini digunakan dengan M3, M3 MaterialTheme akan memperbarui
LocalSwipeToDismissBackgroundScrimColor dan
LocalSwipeToDismissContentScrimColor.
TransformingLazyColumn
TransformingLazyColumn adalah bagian dari wear.compose.lazy.foundation dan menambahkan
dukungan untuk menskalakan dan mengubah animasi pada item daftar selama scrolling, sehingga meningkatkan pengalaman pengguna.
Mirip dengan ScalingLazyColumn, ini menyediakan
rememberTransformingLazyColumnState() untuk membuat
TransformingLazyColumnState yang diingat di seluruh komposisi.
Untuk menambahkan animasi penskalaan dan pengubahan bentuk, tambahkan kode berikut ke setiap item daftar:
Modifier.transformedHeight, yang memungkinkan Anda menghitung tinggi item yang diubah menggunakanTransformationSpec, Anda dapat menggunakanrememberTransformationSpec()kecuali jika Anda memerlukan penyesuaian lebih lanjut.SurfaceTransformation
val columnState = rememberTransformingLazyColumnState() val contentPadding = rememberResponsiveColumnPadding( first = ColumnItemType.ListHeader, last = ColumnItemType.Button, ) val transformationSpec = rememberTransformationSpec() ScreenScaffold( scrollState = columnState, contentPadding = contentPadding ) { contentPadding -> TransformingLazyColumn( state = columnState, contentPadding = contentPadding ) { item { ListHeader( modifier = Modifier.fillMaxWidth().transformedHeight(this, transformationSpec), transformation = SurfaceTransformation(transformationSpec) ) { Text(text = "Header") } } // ... other items item { Button( modifier = Modifier.fillMaxWidth().transformedHeight(this, transformationSpec), transformation = SurfaceTransformation(transformationSpec), onClick = { /* ... */ }, icon = { Icon( imageVector = Icons.Default.Build, contentDescription = "build", ) }, ) { Text( text = "Build", maxLines = 1, overflow = TextOverflow.Ellipsis, ) } } } }
Link penting
Untuk mempelajari migrasi dari M2.5 ke M3 di Compose lebih lanjut, lihat referensi tambahan berikut.