Material 3 Expressive คือวิวัฒนาการขั้นถัดไปของ Material Design ซึ่งรวมถึง การกำหนดธีม คอมโพเนนต์ และฟีเจอร์การปรับเปลี่ยนในแบบของคุณที่อัปเดตแล้ว เช่น สีแบบเปลี่ยนอัตโนมัติ
คู่มือนี้มุ่งเน้นการย้ายข้อมูลจากไลบรารี Jetpack ของ Wear Compose Material 2.5 (androidx.wear.compose) ไปยังไลบรารี Jetpack ของ Wear Compose Material 3 (androidx.wear.compose.material3) สำหรับแอป
แนวทาง
หากต้องการย้ายข้อมูลโค้ดแอปจาก M2.5 ไปยัง M3 ให้ใช้วิธีเดียวกันกับที่อธิบายไว้ ในคำแนะนำในการย้ายข้อมูล Material Compose สำหรับโทรศัพท์ โดยเฉพาะอย่างยิ่ง
- คุณไม่ควรใช้ทั้ง M2.5 และ M3 ในแอปเดียวในระยะยาว
- ใช้แนวทางแบบแบ่งระยะ
การขึ้นต่อกัน
M3 มีแพ็กเกจและเวอร์ชันแยกต่างหากจาก M2.5 ดังนี้
M2.5
implementation("androidx.wear.compose:compose-material:1.4.0")
M3
implementation("androidx.wear.compose:compose-material3:1.6.0-alpha04")
ดู M3 เวอร์ชันล่าสุดได้ในหน้ารุ่น Wear Compose Material 3
ไลบรารี Wear Compose Foundation เวอร์ชัน 1.6.0-alpha04 ได้เปิดตัว
คอมโพเนนต์ใหม่บางรายการที่ออกแบบมาให้ทำงานร่วมกับคอมโพเนนต์ Material 3
ในทำนองเดียวกัน SwipeDismissableNavHost จากไลบรารีการนำทางของ Wear Compose จะมีภาพเคลื่อนไหวที่อัปเดตเมื่อเรียกใช้ใน Wear OS 6 (API ระดับ 36) ขึ้นไป เมื่ออัปเดตเป็น Wear Compose Material เวอร์ชัน 3 เราขอแนะนำให้อัปเดต Wear Compose Foundation และไลบรารีการนำทางด้วย
implementation("androidx.wear.compose:compose-foundation:1.6.0-alpha04")
implementation("androidx.wear.compose:compose-navigation:1.6.0-alpha04")
ธีม
ทั้งใน M2.5 และ M3 องค์ประกอบธีมมีชื่อว่า MaterialTheme แต่
แพ็กเกจการนำเข้าและพารามิเตอร์จะแตกต่างกัน ใน M3 เราได้เปลี่ยนชื่อพารามิเตอร์ Colors เป็น ColorScheme และได้เปิดตัว MotionScheme สำหรับการใช้
การเปลี่ยน
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
)
สี
ระบบสีใน M3 แตกต่างจาก M2.5 อย่างมาก พารามิเตอร์จำนวนสี
เพิ่มขึ้น มีชื่อต่างกัน และแมปกับ
คอมโพเนนต์ M3 แตกต่างกัน ใน Compose การตั้งค่านี้จะมีผลกับคลาส M2.5 Colors, คลาส M3
ColorScheme และฟังก์ชันที่เกี่ยวข้อง
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
)
ตารางต่อไปนี้อธิบายความแตกต่างที่สําคัญระหว่าง M2.5 กับ M3
M2.5 |
M3 |
|---|---|
|
เปลี่ยนชื่อเป็น |
13 สี |
28 สี |
ไม่มี |
การกำหนดธีมสีแบบเปลี่ยนอัตโนมัติใหม่ |
ไม่มี |
สีระดับที่ 3 ใหม่เพื่อการแสดงออกที่มากขึ้น |
การใช้ธีมสีแบบเปลี่ยนอัตโนมัติ
ฟีเจอร์ใหม่ใน M3 คือการกำหนดธีมสีแบบไดนามิก หากผู้ใช้เปลี่ยน สีหน้าปัด สีใน UI จะเปลี่ยนให้ตรงกัน
ใช้ฟังก์ชัน dynamicColorScheme เพื่อใช้รูปแบบสีแบบไดนามิก
และระบุ defaultColorScheme เป็นตัวเลือกสำรองในกรณีที่รูปแบบสีแบบไดนามิก
ไม่พร้อมใช้งาน
@Composable
fun myApp() {
val myColorScheme = myBrandColors()
val dynamicColorScheme = dynamicColorScheme(LocalContext.current)
MaterialTheme(colorScheme = dynamicColorScheme ?: myBrandColors) {...}
}
การพิมพ์
ระบบการพิมพ์ใน M3 แตกต่างจาก M2 และมีฟีเจอร์ต่อไปนี้
- รูปแบบข้อความใหม่ 9 แบบ
- แบบอักษรแบบยืดหยุ่นซึ่งช่วยให้ปรับแต่งสเกลแบบอักษรสำหรับ ความหนา ความกว้าง และความกลมต่างๆ ได้
AnimatedTextซึ่งใช้แบบอักษรแบบยืดหยุ่น
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
)
แบบอักษร Flex
แบบอักษรแบบยืดหยุ่นช่วยให้นักออกแบบระบุความกว้างและน้ำหนักของแบบอักษรสำหรับขนาดที่เฉพาะเจาะจงได้
รูปแบบข้อความ
TextStyle ต่อไปนี้พร้อมใช้งานใน M3 โดยค่าเริ่มต้น M3 จะใช้คอมโพเนนต์ต่างๆ เหล่านี้
การพิมพ์ |
TextStyle |
|---|---|
จอแสดงผล |
displayLarge, displayMedium, displaySmall |
ชื่อ |
titleLarge, titleMedium, titleSmall |
ป้ายกำกับ |
labelLarge, labelMedium, labelSmall |
เนื้อความ |
bodyLarge, bodyMedium, bodySmall, bodyExtraSmall |
ตัวเลข |
numeralExtraLarge, numeralLarge, numeralMedium, numeralSmall, numeralExtraSmall |
เส้นโค้ง |
arcLarge, arcMedium, arcSmall |
รูปทรง
ระบบรูปร่างใน M3 แตกต่างจาก M2 จำนวนพารามิเตอร์รูปร่าง เพิ่มขึ้น มีการตั้งชื่อพารามิเตอร์แตกต่างกัน และมีการแมปกับคอมโพเนนต์ M3 แตกต่างกัน ขนาดรูปร่างที่พร้อมใช้งานมีดังนี้
- เล็กพิเศษ
- เล็ก
- ปานกลาง
- ใหญ่
- ใหญ่พิเศษ
ใน Compose จะมีผลกับคลาส M2 Shapes และคลาส M3
Shapes ดังนี้
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
)
ใช้การแมปพารามิเตอร์รูปร่างจากย้ายข้อมูลจาก Material 2 ไปยัง Material 3 ใน Compose เป็นจุดเริ่มต้น
การเปลี่ยนรูปร่าง
M3 ขอแนะนำการเปลี่ยนรูปร่าง: ตอนนี้รูปร่างจะเปลี่ยนไปตามการโต้ตอบ
ลักษณะการทำงานของการเปลี่ยนรูปร่างมีให้ใช้งานเป็นรูปแบบต่างๆ ในปุ่มกลม หลายปุ่ม โปรดดูรายการปุ่มต่อไปนี้ที่รองรับการเปลี่ยนรูปร่าง
ปุ่ม |
ฟังก์ชันการเปลี่ยนรูปร่าง |
|---|---|
|
IconButtonDefaults.animatedShape() จะเคลื่อนไหวปุ่มไอคอนเมื่อกด |
|
IconToggleButtonDefaults.animatedShape() จะเคลื่อนไหวปุ่มสลับไอคอนเมื่อกดและ IconToggleButtonDefaults.variantAnimatedShapes() จะแสดงภาพเคลื่อนไหวของปุ่มสลับไอคอนเมื่อกดและเลือก/ยกเลิกการเลือก |
|
TextButtonDefaults.animatedShape() จะทำให้ปุ่มข้อความเคลื่อนไหวเมื่อกด |
|
TextToggleButtonDefaults.animatedShapes() จะทำให้การสลับข้อความเคลื่อนไหวเมื่อกด และ TextToggleButtonDefaults.variantAnimatedShapes() จะทำให้การสลับข้อความเคลื่อนไหวเมื่อกดและเลือก/ยกเลิกการเลือก |
คอมโพเนนต์และเลย์เอาต์
คอมโพเนนต์และเลย์เอาต์ส่วนใหญ่จาก M2.5 พร้อมใช้งานใน M3 อย่างไรก็ตาม คอมโพเนนต์และเลย์เอาต์บางอย่างของ M3 ไม่มีใน M2.5 นอกจากนี้ คอมโพเนนต์ M3 บางรายการ ยังมีตัวแปรมากกว่าคอมโพเนนต์ที่เทียบเท่าใน M2.5
แม้ว่าคอมโพเนนต์บางอย่างจะต้องพิจารณาเป็นพิเศษ แต่เราขอแนะนำให้ใช้การแมปฟังก์ชันต่อไปนี้เป็นจุดเริ่มต้น
รายการคอมโพเนนต์ Material 3 ทั้งหมดมีดังนี้
Material 3 |
คอมโพเนนต์ที่เทียบเท่า Material 2.5 (หากไม่ใช่คอมโพเนนต์ใหม่ใน M3) |
|---|---|
ใหม่ |
|
ใหม่ |
|
android.wear.compose.material.Scaffold (พร้อม androidx.wear.compose.material3.ScreenScaffold ) |
|
ใหม่ |
|
androidx.wear.compose.material.ToggleChip ที่มีตัวควบคุมการเปิด/ปิดช่องทำเครื่องหมาย |
|
androidx.wear.compose.material.Chip (เฉพาะเมื่อไม่จำเป็นต้องมีพื้นหลัง) |
|
ใหม่ |
|
ใหม่ |
|
ใหม่ |
|
androidx.wear.compose.material.Chip เมื่อต้องใช้พื้นหลังปุ่มสีโทน |
|
ใหม่ |
|
ใหม่ |
|
ใหม่ |
|
ใหม่ |
|
ใหม่ |
|
androidx.wear.compose.material.ToggleChip ที่มีตัวควบคุมการสลับปุ่มตัวเลือก |
|
android.wear.compose.material.Scaffold (พร้อม androidx.wear.compose material3.AppScaffold) |
|
androidx.wear.compose.material3.SegmentedCircularProgressIndicator |
ใหม่ |
androidx.wear.compose.material.SwipeToRevealCard และ androidx.wear.compose.material.SwipeToRevealChip |
|
androidx.wear.compose.material.ToggleChip พร้อมตัวควบคุมการสลับสวิตช์ |
|
ใหม่ |
และสุดท้ายคือรายการคอมโพเนนต์ที่เกี่ยวข้องบางรายการจากไลบรารี Wear Compose Foundation ซึ่งเปิดตัวครั้งแรกในเวอร์ชัน 1.6.0-alpha04
Wear Compose Foundation 1.6.0-alpha04 |
|
|---|---|
ใช้เพื่อใส่คำอธิบายประกอบที่ Composable ในแอปพลิเคชัน เพื่อติดตามส่วนที่ใช้งานอยู่ของการจัดองค์ประกอบและประสานงานโฟกัส |
|
เครื่องมือเปลี่ยนหน้าแบบเลื่อนแนวนอนที่สร้างขึ้นจากคอมโพเนนต์ Compose Foundation พร้อมการเพิ่มประสิทธิภาพเฉพาะ Wear เพื่อปรับปรุงประสิทธิภาพและการปฏิบัติตามหลักเกณฑ์ของ Wear OS |
|
เครื่องมือเปลี่ยนหน้าแบบเลื่อนแนวตั้งที่สร้างขึ้นจากคอมโพเนนต์ Compose Foundation พร้อมการเพิ่มประสิทธิภาพเฉพาะ Wear เพื่อปรับปรุงประสิทธิภาพและปฏิบัติตามหลักเกณฑ์ของ Wear OS |
|
ใช้แทน |
|
ปุ่ม
ปุ่มใน M3 แตกต่างจาก M2.5 ชิป M2.5 ถูกแทนที่ด้วย
ปุ่ม การติดตั้งใช้งาน Button จะระบุค่าเริ่มต้นสำหรับ Text
maxLines และ textAlign คุณจะลบล้างค่าเริ่มต้นเหล่านั้นได้ในองค์ประกอบ 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 ยังมีปุ่มรูปแบบใหม่ด้วย ดูได้ที่ภาพรวมเอกสารอ้างอิง Compose Material 3 API
M3 เปิดตัวปุ่มใหม่: EdgeButton EdgeButton มีให้เลือก 4 ขนาด ได้แก่ เล็กมาก เล็ก กลาง และใหญ่ EdgeButton
การติดตั้งใช้งานจะระบุค่าเริ่มต้นสำหรับ maxLines ตามขนาด
ซึ่งปรับแต่งได้
หากคุณใช้ TransformingLazyColumn และ ScalingLazyColumn ให้ส่ง EdgeButton ไปยัง ScreenScaffold เพื่อให้รูปร่างเปลี่ยนไปตามการเลื่อน
ดูโค้ดต่อไปนี้เพื่อดูวิธีใช้ EdgeButton กับ
ScreenScaffold และ 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
โครงสร้างใน M3 แตกต่างจาก M2.5 ใน M3 AppScaffold และ
ScreenScaffoldแบบประกอบใหม่ได้แทนที่ Scaffold แล้ว AppScaffold และ
ScreenScaffold จะวางโครงสร้างของหน้าจอและประสานงานการเปลี่ยนของ
คอมโพเนนต์ ScrollIndicator และ TimeText
AppScaffold ช่วยให้องค์ประกอบหน้าจอแบบคงที่ เช่น TimeText ยังคงมองเห็นได้
ในระหว่างการเปลี่ยนหน้าในแอป เช่น การปัดเพื่อปิด โดยมีช่องสำหรับ
เนื้อหาแอปพลิเคชันหลัก ซึ่งโดยปกติแล้วจะจัดหาโดยคอมโพเนนต์การนำทาง เช่น SwipeDismissableNavHost
คุณประกาศ AppScaffold หนึ่งรายการสำหรับกิจกรรมและใช้ ScreenScaffold สำหรับแต่ละหน้าจอ
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 // ...
หากคุณใช้ HorizontalPager กับ HorizontalPagerIndicator คุณสามารถย้ายข้อมูลไปยัง HorizontalPagerScaffold ได้ HorizontalPagerScaffold อยู่ภายใน AppScaffold AppScaffold และ HorizontalPagerScaffold จะวางโครงสร้างของ Pager และประสานงานการเปลี่ยนของคอมโพเนนต์ HorizontalPageIndicator และ TimeText
HorizontalPagerScaffold จะแสดง HorizontalPageIndicator ที่
กึ่งกลางด้านท้ายของหน้าจอโดยค่าเริ่มต้น และประสานงานการแสดงและการซ่อน
TimeText และ HorizontalPageIndicator ตามว่า Pager มีการ
แบ่งหน้าหรือไม่ ซึ่งจะกำหนดโดย PagerState
นอกจากนี้ยังมีAnimatedPageคอมโพเนนต์ใหม่ ซึ่งจะเคลื่อนไหวหน้าภายใน
Pager ด้วยเอฟเฟกต์การปรับขนาดและเอฟเฟกต์ Scrim ตามตำแหน่งของหน้า
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") } } } } } } } }
สุดท้าย M3 ได้เปิดตัว VerticalPagerScaffold ซึ่งมีรูปแบบเดียวกับ 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 {
…
}
}
ตัวยึดตำแหน่ง
API มีการเปลี่ยนแปลงบางอย่างระหว่าง M2.5 กับ M3
Placeholder.PlaceholderDefaults มีตัวแก้ไข 2 รายการดังนี้
Modifier.placeholderซึ่งจะวาดแทนเนื้อหาที่ยังไม่ได้โหลด- เอฟเฟกต์การสั่นไหวของตัวยึดตำแหน่ง
Modifier.placeholderShimmerซึ่ง แสดงเอฟเฟกต์การสั่นไหวของตัวยึดตำแหน่งที่ทำงานในลูปภาพเคลื่อนไหวขณะ รอให้ข้อมูลโหลด
ดูการเปลี่ยนแปลงเพิ่มเติมในคอมโพเนนต์ Placeholder ได้ในตารางต่อไปนี้
M2.5 |
M3 |
|---|---|
|
ถูกนำออกแล้ว |
|
ถูกนำออกแล้ว |
|
เปลี่ยนชื่อเป็น |
|
ถูกนำออกแล้ว |
|
ถูกนำออกแล้ว |
|
ถูกนำออกแล้ว |
|
ถูกนำออกแล้ว |
SwipeDismissableNavHost
SwipeDismissableNavHost เป็นส่วนหนึ่งของ wear.compose.navigation เมื่อใช้คอมโพเนนต์นี้กับ M3 ทาง M3 MaterialTheme จะอัปเดต LocalSwipeToDismissBackgroundScrimColor และ LocalSwipeToDismissContentScrimColor
TransformingLazyColumn
TransformingLazyColumn เป็นส่วนหนึ่งของ wear.compose.lazy.foundation และเพิ่ม
การรองรับการปรับขนาดและภาพเคลื่อนไหวที่เปลี่ยนรูปร่างในรายการระหว่างการเลื่อน
เพื่อปรับปรุงประสบการณ์ของผู้ใช้
เช่นเดียวกับ ScalingLazyColumn ซึ่งมี
rememberTransformingLazyColumnState() สำหรับสร้าง
TransformingLazyColumnState ที่ระบบจดจำได้ในทุกองค์ประกอบ
หากต้องการเพิ่มภาพเคลื่อนไหวการปรับขนาดและการมอร์ฟ ให้เพิ่มสิ่งต่อไปนี้ลงในรายการแต่ละรายการ
Modifier.transformedHeightซึ่งช่วยให้คุณคำนวณความสูงที่แปลงแล้วของรายการโดยใช้TransformationSpecได้ คุณสามารถใช้rememberTransformationSpec()ได้ เว้นแต่คุณต้องการปรับแต่งเพิ่มเติม- A
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, ) } } } }
ลิงก์ที่มีประโยชน์
ดูข้อมูลเพิ่มเติมเกี่ยวกับการย้ายข้อมูลจาก M2.5 ไปยัง M3 ใน Compose ได้จาก แหล่งข้อมูลเพิ่มเติมต่อไปนี้