1. บทนำ
ใน Codelab นี้ คุณจะได้เรียนรู้เกี่ยวกับการกำหนดธีมแอปใน Jetpack Compose โดยใช้ Material Design 3 นอกจากนี้ คุณยังจะได้เรียนรู้เกี่ยวกับองค์ประกอบสำคัญของรูปแบบสี การออกแบบตัวอักษร และรูปร่างของ Material Design 3 ซึ่งจะช่วยให้คุณจัดธีมแอปพลิเคชันในแบบที่เป็นส่วนตัวและเข้าถึงได้
นอกจากนี้ คุณจะได้ดูการรองรับการกำหนดธีมแบบไดนามิกพร้อมกับระดับการเน้นที่แตกต่างกัน
สิ่งที่คุณจะได้เรียนรู้
ใน Codelab นี้ คุณจะได้เรียนรู้สิ่งต่อไปนี้
- ลักษณะสำคัญของการกำหนดธีม Material 3
- รูปแบบสี Material 3 และวิธีสร้างธีมสำหรับแอป
- วิธีรองรับการจัดธีมแบบไดนามิกและธีมสว่าง/มืดสำหรับแอป
- การจัดรูปแบบข้อความและรูปร่างเพื่อปรับแต่งแอปในแบบของคุณ
- คอมโพเนนต์ Material 3 และการปรับแต่งเพื่อจัดรูปแบบแอป
สิ่งที่คุณจะสร้าง
ใน Codelab นี้ คุณจะกำหนดธีมให้กับโปรแกรมรับส่งอีเมลชื่อ Reply คุณเริ่มต้นด้วยแอปพลิเคชันที่ไม่ได้จัดรูปแบบโดยใช้ธีมพื้นฐาน และจะนำสิ่งที่ได้เรียนรู้ไปใช้เพื่อจัดธีมแอปพลิเคชันและรองรับธีมมืด

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

จุดสิ้นสุดของ Codelab การกำหนดธีมที่มีการกำหนดธีมสีอ่อนและการกำหนดธีมแบบไดนามิกสีอ่อน

จุดสิ้นสุดของโค้ดแล็บการกำหนดธีมที่มีการกำหนดธีมสีเข้มและการกำหนดธีมแบบไดนามิกสีเข้ม
สิ่งที่คุณจะต้องมี
- Android Studio เวอร์ชันล่าสุด
- มีประสบการณ์พื้นฐานเกี่ยวกับภาษา Kotlin
- ความเข้าใจพื้นฐานเกี่ยวกับ Jetpack Compose
- คุ้นเคยกับเลย์เอาต์ Compose พื้นฐาน เช่น Row, Column และ Modifier
2. การเริ่มต้นใช้งาน
ในขั้นตอนนี้ คุณจะดาวน์โหลดโค้ดทั้งหมดของแอป Reply ซึ่งคุณจะจัดรูปแบบใน Codelab นี้
รับโค้ด
คุณดูโค้ดสำหรับ Codelab นี้ได้ในที่เก็บ GitHub ของ android-compose-codelabs หากต้องการโคลน ให้เรียกใช้คำสั่งต่อไปนี้
$ git clone https://github.com/googlecodelabs/android-compose-codelabs
หรือจะดาวน์โหลดไฟล์ ZIP 2 ไฟล์ก็ได้ โดยทำดังนี้
ดูแอปตัวอย่าง
โค้ดที่คุณเพิ่งดาวน์โหลดมีโค้ดสำหรับ Compose Codelab ที่พร้อมใช้งานทั้งหมด หากต้องการทำ Codelab นี้ให้เสร็จสมบูรณ์ ให้เปิดโปรเจ็กต์ ThemingCodelab ใน Android Studio
เราขอแนะนำให้คุณเริ่มต้นด้วยโค้ดใน Branch หลักและทำตาม Codelab ทีละขั้นตอนตามที่คุณสะดวก คุณเรียกใช้เวอร์ชันใดก็ได้ใน Android Studio ได้ทุกเมื่อโดยเปลี่ยนสาขา Git ของโปรเจ็กต์
สำรวจรหัสเริ่มต้น
โค้ดหลักมีแพ็กเกจ UI ซึ่งมีแพ็กเกจและไฟล์หลักต่อไปนี้ที่คุณจะโต้ตอบด้วย
MainActivity.kt- กิจกรรมจุดแรกเข้าที่คุณเริ่มแอป Replycom.example.reply.ui.theme- แพ็กเกจนี้มีธีม การออกแบบตัวอักษร และรูปแบบสี คุณจะเพิ่มการจัดธีม Material ในแพ็กเกจนี้com.example.reply.ui.components- มีคอมโพเนนต์ที่กำหนดเองของแอป เช่น รายการในลิสต์ แถบแอป ฯลฯ คุณจะใช้ธีมกับคอมโพเนนต์เหล่านี้ReplyApp.kt- นี่คือฟังก์ชันที่ประกอบกันได้หลักของเราซึ่งเป็นจุดเริ่มต้นของแผนผัง UI คุณจะใช้การจัดธีมระดับบนสุดในไฟล์นี้
Codelab นี้จะเน้นที่ไฟล์แพ็กเกจ ui
3. การกำหนดธีม Material 3
Jetpack Compose มีการติดตั้งใช้งาน Material Design ซึ่งเป็นระบบการออกแบบที่ครอบคลุมสำหรับการสร้างอินเทอร์เฟซดิจิทัล คอมโพเนนต์ของ Material Design (ปุ่ม การ์ด สวิตช์ ฯลฯ) สร้างขึ้นบนการกำหนดธีม Material ซึ่งเป็นวิธีที่เป็นระบบในการปรับแต่ง Material Design เพื่อให้แสดงถึงแบรนด์ของผลิตภัณฑ์ได้ดียิ่งขึ้น
ธีม Material 3 ประกอบด้วยระบบย่อยต่อไปนี้เพื่อเพิ่มการกำหนดธีมลงในแอป รูปแบบสี การพิมพ์ และรูปร่าง เมื่อปรับแต่งค่าเหล่านี้ การเปลี่ยนแปลงจะแสดงในคอมโพเนนต์ M3 ที่คุณใช้สร้างแอปโดยอัตโนมัติ มาดูแต่ละระบบย่อยและนำไปใช้ในแอปตัวอย่างกัน

ระบบย่อยของสี การพิมพ์ และรูปร่างของ Material 3
4. รูปแบบสี
รากฐานของรูปแบบสีคือชุดสีหลัก 5 สี ซึ่งแต่ละสีจะเชื่อมโยงกับชุดสี 13 โทนที่คอมโพเนนต์ Material 3 ใช้

สีหลักพื้นฐาน 5 สีสำหรับการสร้างธีม M3
จากนั้นจะมีการระบุสีเน้นแต่ละสี (หลัก รอง และระดับที่ 3) ใน 4 สีที่เข้ากันได้ซึ่งมีโทนสีต่างกันสำหรับการจับคู่ การกำหนดการเน้น และการแสดงภาพ

สีโทน 4 สีของสีเน้นหลัก รอง และตติยภูมิ
ในทำนองเดียวกัน สีกลางจะแบ่งออกเป็น 4 โทนที่เข้ากันได้ซึ่งใช้สำหรับพื้นผิวและพื้นหลัง นอกจากนี้ ยังมีความสำคัญในการเน้นไอคอนข้อความเมื่อวางบนพื้นผิวใดก็ตาม

สีโทน 4 สีของสีกลางพื้นฐาน
อ่านข้อมูลเพิ่มเติมเกี่ยวกับรูปแบบสีและบทบาทของสี
การสร้างรูปแบบสี
แม้ว่าคุณจะสร้าง ColorScheme ที่กำหนดเองด้วยตนเองได้ แต่การสร้างโดยใช้สีต้นทางจากแบรนด์มักจะง่ายกว่า เครื่องมือ Material Theme Builder ช่วยให้คุณทำสิ่งนี้ได้ และยังส่งออกโค้ดการจัดธีม Compose ได้ด้วย (ไม่บังคับ)
คุณเลือกสีใดก็ได้ตามต้องการ แต่สำหรับกรณีการใช้งานของเรา คุณจะต้องใช้สีหลักเริ่มต้นของ Reply #825500 คลิกสีหลักในส่วนสีหลักทางด้านซ้าย แล้วเพิ่มโค้ดในเครื่องมือเลือกสี

การเพิ่มรหัสสีหลักใน Material Theme Builder
เมื่อเพิ่มสีหลักใน Material Theme Builder แล้ว คุณควรเห็นธีมต่อไปนี้และตัวเลือกในการส่งออกที่มุมขวาบน สำหรับ Codelab นี้ คุณจะส่งออกธีมใน Jetpack Compose

Material Theme Builder พร้อมตัวเลือกในการส่งออกที่มุมขวาบน
สีหลัก #825500 จะสร้างธีมต่อไปนี้ที่คุณจะเพิ่มลงในแอป Material 3 มีบทบาทสีที่หลากหลายเพื่อแสดงสถานะ ความโดดเด่น และการเน้นของคอมโพเนนต์ได้อย่างยืดหยุ่น

ส่งออกรูปแบบสีอ่อนและสีเข้มจากสีหลัก
The Color.ktไฟล์ที่สร้างขึ้นจะมีสีของธีมพร้อมบทบาททั้งหมดที่กำหนดไว้สำหรับทั้งสีของธีมสว่างและธีมมืด
Color.kt
package com.example.reply.ui.theme
import androidx.compose.ui.graphics.Color
val md_theme_light_primary = Color(0xFF825500)
val md_theme_light_onPrimary = Color(0xFFFFFFFF)
val md_theme_light_primaryContainer = Color(0xFFFFDDB3)
val md_theme_light_onPrimaryContainer = Color(0xFF291800)
val md_theme_light_secondary = Color(0xFF6F5B40)
val md_theme_light_onSecondary = Color(0xFFFFFFFF)
val md_theme_light_secondaryContainer = Color(0xFFFBDEBC)
val md_theme_light_onSecondaryContainer = Color(0xFF271904)
val md_theme_light_tertiary = Color(0xFF51643F)
val md_theme_light_onTertiary = Color(0xFFFFFFFF)
val md_theme_light_tertiaryContainer = Color(0xFFD4EABB)
val md_theme_light_onTertiaryContainer = Color(0xFF102004)
val md_theme_light_error = Color(0xFFBA1A1A)
val md_theme_light_errorContainer = Color(0xFFFFDAD6)
val md_theme_light_onError = Color(0xFFFFFFFF)
val md_theme_light_onErrorContainer = Color(0xFF410002)
val md_theme_light_background = Color(0xFFFFFBFF)
val md_theme_light_onBackground = Color(0xFF1F1B16)
val md_theme_light_surface = Color(0xFFFFFBFF)
val md_theme_light_onSurface = Color(0xFF1F1B16)
val md_theme_light_surfaceVariant = Color(0xFFF0E0CF)
val md_theme_light_onSurfaceVariant = Color(0xFF4F4539)
val md_theme_light_outline = Color(0xFF817567)
val md_theme_light_inverseOnSurface = Color(0xFFF9EFE7)
val md_theme_light_inverseSurface = Color(0xFF34302A)
val md_theme_light_inversePrimary = Color(0xFFFFB951)
val md_theme_light_shadow = Color(0xFF000000)
val md_theme_light_surfaceTint = Color(0xFF825500)
val md_theme_light_outlineVariant = Color(0xFFD3C4B4)
val md_theme_light_scrim = Color(0xFF000000)
val md_theme_dark_primary = Color(0xFFFFB951)
val md_theme_dark_onPrimary = Color(0xFF452B00)
val md_theme_dark_primaryContainer = Color(0xFF633F00)
val md_theme_dark_onPrimaryContainer = Color(0xFFFFDDB3)
val md_theme_dark_secondary = Color(0xFFDDC2A1)
val md_theme_dark_onSecondary = Color(0xFF3E2D16)
val md_theme_dark_secondaryContainer = Color(0xFF56442A)
val md_theme_dark_onSecondaryContainer = Color(0xFFFBDEBC)
val md_theme_dark_tertiary = Color(0xFFB8CEA1)
val md_theme_dark_onTertiary = Color(0xFF243515)
val md_theme_dark_tertiaryContainer = Color(0xFF3A4C2A)
val md_theme_dark_onTertiaryContainer = Color(0xFFD4EABB)
val md_theme_dark_error = Color(0xFFFFB4AB)
val md_theme_dark_errorContainer = Color(0xFF93000A)
val md_theme_dark_onError = Color(0xFF690005)
val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6)
val md_theme_dark_background = Color(0xFF1F1B16)
val md_theme_dark_onBackground = Color(0xFFEAE1D9)
val md_theme_dark_surface = Color(0xFF1F1B16)
val md_theme_dark_onSurface = Color(0xFFEAE1D9)
val md_theme_dark_surfaceVariant = Color(0xFF4F4539)
val md_theme_dark_onSurfaceVariant = Color(0xFFD3C4B4)
val md_theme_dark_outline = Color(0xFF9C8F80)
val md_theme_dark_inverseOnSurface = Color(0xFF1F1B16)
val md_theme_dark_inverseSurface = Color(0xFFEAE1D9)
val md_theme_dark_inversePrimary = Color(0xFF825500)
val md_theme_dark_shadow = Color(0xFF000000)
val md_theme_dark_surfaceTint = Color(0xFFFFB951)
val md_theme_dark_outlineVariant = Color(0xFF4F4539)
val md_theme_dark_scrim = Color(0xFF000000)
val seed = Color(0xFF825500)
The Theme.kt ไฟล์ที่สร้างขึ้นมีการตั้งค่าสำหรับรูปแบบสีสว่างและสีเข้ม รวมถึงธีมของแอป นอกจากนี้ ยังมีฟังก์ชันที่ประกอบกันได้สำหรับการกำหนดธีมหลัก AppTheme()
Theme.kt
package com.example.reply.ui.theme
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.runtime.Composable
private val LightColors = lightColorScheme(
primary = md_theme_light_primary,
onPrimary = md_theme_light_onPrimary,
primaryContainer = md_theme_light_primaryContainer,
onPrimaryContainer = md_theme_light_onPrimaryContainer,
secondary = md_theme_light_secondary,
onSecondary = md_theme_light_onSecondary,
secondaryContainer = md_theme_light_secondaryContainer,
onSecondaryContainer = md_theme_light_onSecondaryContainer,
tertiary = md_theme_light_tertiary,
onTertiary = md_theme_light_onTertiary,
tertiaryContainer = md_theme_light_tertiaryContainer,
onTertiaryContainer = md_theme_light_onTertiaryContainer,
error = md_theme_light_error,
errorContainer = md_theme_light_errorContainer,
onError = md_theme_light_onError,
onErrorContainer = md_theme_light_onErrorContainer,
background = md_theme_light_background,
onBackground = md_theme_light_onBackground,
surface = md_theme_light_surface,
onSurface = md_theme_light_onSurface,
surfaceVariant = md_theme_light_surfaceVariant,
onSurfaceVariant = md_theme_light_onSurfaceVariant,
outline = md_theme_light_outline,
inverseOnSurface = md_theme_light_inverseOnSurface,
inverseSurface = md_theme_light_inverseSurface,
inversePrimary = md_theme_light_inversePrimary,
surfaceTint = md_theme_light_surfaceTint,
outlineVariant = md_theme_light_outlineVariant,
scrim = md_theme_light_scrim,
)
private val DarkColors = darkColorScheme(
primary = md_theme_dark_primary,
onPrimary = md_theme_dark_onPrimary,
primaryContainer = md_theme_dark_primaryContainer,
onPrimaryContainer = md_theme_dark_onPrimaryContainer,
secondary = md_theme_dark_secondary,
onSecondary = md_theme_dark_onSecondary,
secondaryContainer = md_theme_dark_secondaryContainer,
onSecondaryContainer = md_theme_dark_onSecondaryContainer,
tertiary = md_theme_dark_tertiary,
onTertiary = md_theme_dark_onTertiary,
tertiaryContainer = md_theme_dark_tertiaryContainer,
onTertiaryContainer = md_theme_dark_onTertiaryContainer,
error = md_theme_dark_error,
errorContainer = md_theme_dark_errorContainer,
onError = md_theme_dark_onError,
onErrorContainer = md_theme_dark_onErrorContainer,
background = md_theme_dark_background,
onBackground = md_theme_dark_onBackground,
surface = md_theme_dark_surface,
onSurface = md_theme_dark_onSurface,
surfaceVariant = md_theme_dark_surfaceVariant,
onSurfaceVariant = md_theme_dark_onSurfaceVariant,
outline = md_theme_dark_outline,
inverseOnSurface = md_theme_dark_inverseOnSurface,
inverseSurface = md_theme_dark_inverseSurface,
inversePrimary = md_theme_dark_inversePrimary,
surfaceTint = md_theme_dark_surfaceTint,
outlineVariant = md_theme_dark_outlineVariant,
scrim = md_theme_dark_scrim,
)
@Composable
fun AppTheme(
useDarkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable() () -> Unit
) {
val colors = if (!useDarkTheme) {
LightColors
} else {
DarkColors
}
MaterialTheme(
colorScheme = colors,
content = content
)
}
องค์ประกอบหลักสำหรับการใช้ธีมใน Jetpack Compose คือ Composable MaterialTheme
คุณจะรวม MaterialTheme() ที่ประกอบกันได้ไว้ในฟังก์ชัน AppTheme() ซึ่งใช้พารามิเตอร์ 2 รายการ ดังนี้
useDarkTheme- พารามิเตอร์นี้เชื่อมโยงกับฟังก์ชันisSystemInDarkTheme()เพื่อสังเกตการตั้งค่าการจัดธีมของระบบและใช้ธีมสว่างหรือมืด หากต้องการให้แอปอยู่ในธีมสว่างหรือธีมมืดด้วยตนเอง คุณสามารถส่งค่าบูลีนไปยังuseDarkThemeได้content- เนื้อหาที่จะใช้ธีม
Theme.kt
@Composable
fun AppTheme(
useDarkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable() () -> Unit
) {
val colors = if (!useDarkTheme) {
LightColors
} else {
DarkColors
}
MaterialTheme(
colorScheme = colors,
content = content
)
}
หากลองเรียกใช้แอปตอนนี้ คุณจะเห็นว่าแอปมีลักษณะเหมือนเดิม แม้ว่าคุณจะนำเข้ารูปแบบสีใหม่ของเราที่มีสีการจัดธีมใหม่แล้ว แต่คุณก็ยังเห็นการจัดธีมพื้นฐานเนื่องจากยังไม่ได้ใช้ธีมกับแอป Compose

แอปที่มีการกำหนดธีมพื้นฐานเมื่อไม่มีการใช้ธีม
หากต้องการใช้ธีมใหม่ ใน MainActivity.kt ให้ห่อ Composable หลัก ReplyApp ด้วยฟังก์ชันการจัดธีมหลัก AppTheme()
MainActivity.kt
setContent {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
AppTheme {
ReplyApp(/*..*/)
}
}
นอกจากนี้ คุณยังต้องอัปเดตฟังก์ชันแสดงตัวอย่างเพื่อดูธีมที่ใช้กับตัวอย่างแอปด้วย ห่อหุ้ม ReplyApp ที่เขียนด้วย Compose ไว้ภายใน ReplyAppPreview() ด้วย AppTheme เพื่อใช้ธีมกับตัวอย่าง
คุณมีทั้งธีมระบบสว่างและธีมระบบมืดที่กำหนดไว้ในพารามิเตอร์ตัวอย่าง ดังนั้นคุณจะเห็นทั้ง 2 ตัวอย่าง
MainActivity.kt
@Preview(
uiMode = Configuration.UI_MODE_NIGHT_YES,
name = "DefaultPreviewDark"
)
@Preview(
uiMode = Configuration.UI_MODE_NIGHT_NO,
name = "DefaultPreviewLight"
)
@Composable
fun ReplyAppPreview() {
AppTheme {
ReplyApp(
replyHomeUIState = ReplyHomeUIState(
emails = LocalEmailsDataProvider.allEmails
)
)
}
}
หากเรียกใช้แอปตอนนี้ คุณควรเห็นตัวอย่างแอปที่มีสีธีมที่นำเข้าแทนธีมพื้นฐาน

แอปที่มีธีมพื้นฐาน (ซ้าย)
แอปที่มีธีมสีที่นำเข้า (ขวา)

ตัวอย่างแอปธีมสว่างและธีมมืดที่มีธีมสีที่นำเข้า
Material 3 รองรับทั้งรูปแบบสีสว่างและสีเข้ม คุณเพียงแค่รวมแอปกับธีมที่นำเข้าเท่านั้น คอมโพเนนต์ Material 3 ใช้บทบาทสีเริ่มต้น
มาดูบทบาทของสีและการใช้งานก่อนที่คุณจะเริ่มเพิ่มสีลงในแอปกัน
บทบาทของสีและการช่วยเหลือพิเศษ
บทบาทของสีแต่ละสีสามารถใช้ได้ในหลายที่ ขึ้นอยู่กับสถานะ ความโดดเด่น และการเน้นของคอมโพเนนต์

บทบาทของสีหลัก สีรอง และสีระดับที่ 3
สีหลักคือสีพื้นฐานที่ใช้กับคอมโพเนนต์หลัก เช่น ปุ่มที่โดดเด่นและสถานะที่ใช้งานอยู่
ระบบจะใช้สีคีย์รองกับคอมโพเนนต์ที่โดดเด่นน้อยกว่าใน UI เช่น ชิปตัวกรอง
สีคีย์ตติยภูมิใช้เพื่อเน้นสีที่ตัดกัน และสีกลางใช้สำหรับพื้นหลังและพื้นผิวในแอป
ระบบสีของ Material มีค่าเฉดสีและการวัดมาตรฐานที่ใช้เพื่อให้เป็นไปตามอัตราส่วนคอนทราสต์ที่เข้าถึงได้ ใช้สี "on-primary" บน "primary", "on-primary-container" บน "primary-container" และใช้สีเดียวกันกับสีเน้นและสีกลางอื่นๆ เพื่อให้ผู้ใช้เข้าถึงคอนทราสต์ได้
ดูข้อมูลเพิ่มเติมได้ที่บทบาทของสีและการช่วยเหลือพิเศษ
การยกระดับโทนสีและเงา
Material 3 แสดงระดับความสูงโดยใช้การวางซ้อนสีโทนเป็นหลัก นี่เป็นวิธีใหม่ในการแยกความแตกต่างของคอนเทนเนอร์และพื้นผิวจากกัน ซึ่งการเพิ่มระดับโทนสีจะใช้โทนสีที่โดดเด่นมากขึ้นนอกเหนือจากเงา
การยกระดับโทนสีที่ระดับ 2 ซึ่งใช้สีจากช่องสีหลัก
การซ้อนทับระดับความสูงในธีมมืดยังเปลี่ยนเป็นการซ้อนทับสีโทนใน Material Design 3 ด้วย สีซ้อนทับมาจากช่องสีหลัก
M3 Surface ซึ่งเป็น Composable ที่อยู่เบื้องหลังคอมโพเนนต์ M3 ส่วนใหญ่รองรับทั้งการยกระดับแบบโทนสีและแบบเงา
Surface(
modifier = modifier,
tonalElevation = {..}
shadowElevation = {..}
) {
Column(content = content)
}
การเพิ่มสีลงในแอป
หากเรียกใช้แอป คุณจะเห็นสีที่ส่งออกแสดงในแอปที่คอมโพเนนต์ใช้สีเริ่มต้น ตอนนี้เราทราบถึงบทบาทและการใช้งานสีแล้ว มาจัดธีมแอปด้วยบทบาทสีที่ถูกต้องกัน

แอปที่มีธีมสีและคอมโพเนนต์ที่ใช้บทบาทสีเริ่มต้น
สีพื้นผิว
ในหน้าจอหลัก คุณจะเริ่มต้นด้วยการห่อ Composable ของแอปหลักใน Surface() เพื่อเป็นฐานให้วางเนื้อหาของแอปไว้ด้านบน เปิด MainActivity.kt แล้วห่อ Composable ReplyApp() ด้วย Surface
นอกจากนี้ คุณยังต้องระบุระดับความสูงของสีที่ 5.dp เพื่อให้พื้นผิวมีสีของช่องหลัก ซึ่งจะช่วยให้เกิดคอนทราสต์กับรายการในลิสต์และแถบค้นหาที่อยู่ด้านบน โดยค่าเริ่มต้น ระดับสีและเงาสำหรับพื้นผิวคือ 0.dp
MainActivity.kt
AppTheme {
Surface(tonalElevation = 5.dp) {
ReplyApp(
replyHomeUIState = uiState,
// other parameters
)
}
}
หากเรียกใช้แอปพลิเคชันตอนนี้และเห็นทั้งหน้า List และหน้า Detail คุณควรเห็นพื้นผิวสีที่ใช้กับทั้งแอป

พื้นหลังของแอปที่ไม่มีสีพื้นผิวและสีโทนัล (ซ้าย)
พื้นหลังของแอปที่มีการใช้สีพื้นผิวและสีโทน (ขวา)
สีแถบแอป
แถบค้นหาที่กำหนดเองของเราที่ด้านบนไม่มีพื้นหลังที่ชัดเจนตามคำขอการออกแบบ โดยค่าเริ่มต้น ระบบจะเปลี่ยนกลับไปใช้พื้นผิวฐานเริ่มต้น คุณสามารถใส่พื้นหลังเพื่อให้แยกกันอย่างชัดเจน

แถบค้นหาที่กำหนดเองไม่มีพื้นหลัง (ซ้าย)
แถบค้นหาที่กำหนดเองพร้อมพื้นหลัง (ขวา)
ตอนนี้คุณจะแก้ไข ui/components/ReplyAppBars.kt ซึ่งมีแถบแอป คุณจะเพิ่ม MaterialTheme.colorScheme.background ไปยัง Row ของ Composable Modifier
ReplyAppBars.kt
@Composable
fun ReplySearchBar(modifier: Modifier = Modifier) {
Row(
modifier = modifier
.fillMaxWidth()
.padding(16.dp)
.background(MaterialTheme.colorScheme.background),
verticalAlignment = Alignment.CenterVertically
) {
// Search bar content
}
}
ตอนนี้คุณควรเห็นความแตกต่างที่ชัดเจนระหว่างพื้นผิวสีและแถบแอปที่มีสีพื้นหลัง

แถบค้นหาที่มีสีพื้นหลังอยู่ด้านบนของพื้นผิวสี
สีปุ่มการทำงานแบบลอย

FAB ขนาดใหญ่ที่ไม่ได้ใช้ธีม (ซ้าย)
FAB ขนาดใหญ่ตามธีมที่มีสีระดับที่ 3 (ขวา)
ในหน้าจอหลัก คุณสามารถปรับปรุงลักษณะของปุ่มการทำงานแบบลอย (FAB) เพื่อให้โดดเด่นเป็นปุ่มคำกระตุ้นให้ดำเนินการ หากต้องการใช้ฟีเจอร์นี้ คุณจะต้องใช้สีเฉพาะจุดระดับที่ 3 กับปุ่ม
ในไฟล์ ReplyListContent.kt ให้อัปเดต containerColor สำหรับ FAB เป็นสี tertiaryContainer และสีเนื้อหาเป็น onTertiaryContainer เพื่อรักษาการช่วยเหลือพิเศษและความคมชัดของสี
ReplyListContent.kt
ReplyInboxScreen(/*..*/) {
// Email list content
LargeFloatingActionButton(
containerColor = MaterialTheme.colorScheme.tertiaryContainer,
contentColor = MaterialTheme.colorScheme.onTertiaryContainer
){
/*..*/
}
}
เรียกใช้แอปเพื่อดู FAB ที่มีธีม สำหรับ Codelab นี้ คุณจะใช้ LargeFloatingActionButton
สีของการ์ด
รายการอีเมลในหน้าจอหลักใช้คอมโพเนนต์การ์ด โดยค่าเริ่มต้นจะเป็นการ์ดแบบเติมที่ใช้สีพื้นผิวที่แตกต่างกันสำหรับสีคอนเทนเนอร์เพื่อให้แยกความแตกต่างระหว่างสีพื้นผิวกับสีของการ์ดได้อย่างชัดเจน นอกจากนี้ Compose ยังมีการติดตั้งใช้งาน ElevatedCard และ OutlinedCard ด้วย
คุณยังไฮไลต์รายการที่สำคัญเพิ่มเติมได้โดยระบุโทนสีรอง คุณจะแก้ไข ui/components/ReplyEmailListItem.kt ได้โดยการอัปเดตสีคอนเทนเนอร์การ์ดโดยใช้ CardDefaults.cardColors() สำหรับอีเมลสำคัญ
ReplyEmailListItem.kt
Card(
modifier = modifier
.padding(horizontal = 16.dp, vertical = 4.dp)
.semantics { selected = isSelected }
.clickable { navigateToDetail(email.id) },
colors = CardDefaults.cardColors(
containerColor = if (email.isImportant)
MaterialTheme.colorScheme.secondaryContainer
else MaterialTheme.colorScheme.surfaceVariant
)
){
/*..*/
}

ไฮไลต์รายการโดยใช้สีคอนเทนเนอร์รองบนพื้นผิวโทนสี
สีของรายการรายละเอียด
ตอนนี้คุณได้จัดธีมหน้าจอหลักแล้ว ดูหน้ารายละเอียดโดยคลิกรายการใดก็ได้ในรายการอีเมล

หน้ารายละเอียดเริ่มต้นที่ไม่มีรายการที่มีธีม (ซ้าย)
รายการในลิสต์รายละเอียดที่มีการใช้ธีมพื้นหลัง (ขวา)
รายการของคุณไม่มีการใช้สี จึงกลับไปใช้สีพื้นผิวแบบโทนสีเริ่มต้น คุณจะใช้สีพื้นหลังกับรายการเพื่อสร้างการแยก และเพิ่มระยะห่างภายในเพื่อให้มีช่องว่างรอบพื้นหลัง
ReplyEmailThreadItem.kt
@Composable
fun ReplyEmailThreadItem(
email: Email,
modifier: Modifier = Modifier
) {
Column(
modifier = modifier
.fillMaxWidth()
.padding(16.dp)
.background(MaterialTheme.colorScheme.background)
.padding(20.dp)
) {
// List item content
}
}
คุณจะเห็นว่าเพียงแค่ระบุพื้นหลัง คุณก็แยกพื้นผิวสีและรายการได้อย่างชัดเจน
ตอนนี้คุณมีทั้งหน้าแรกและหน้ารายละเอียดที่มีบทบาทและการใช้งานสีที่ถูกต้องแล้ว มาดูกันว่าแอปของคุณจะใช้ประโยชน์จากสีแบบไดนามิกเพื่อมอบประสบการณ์การใช้งานที่ปรับเปลี่ยนในแบบของคุณและสอดคล้องกันมากยิ่งขึ้นได้อย่างไร
5. การเพิ่มสีแบบไดนามิกลงในแอป
สีแบบไดนามิกเป็นส่วนสำคัญของ Material 3 ซึ่งอัลกอริทึมจะดึงสีแบบกำหนดเองจากวอลเปเปอร์ของผู้ใช้เพื่อนำไปใช้กับแอปและ UI ของระบบ
การกำหนดธีมแบบไดนามิกช่วยให้แอปปรับเปลี่ยนในแบบของคุณมากขึ้น นอกจากนี้ ยังมอบประสบการณ์การใช้งานที่สอดคล้องและราบรื่นแก่ผู้ใช้ด้วยธีมของระบบ
สีแบบไดนามิกพร้อมใช้งานใน Android 12 ขึ้นไป หากมีสีแบบไดนามิกให้ใช้งาน คุณจะตั้งค่ารูปแบบสีแบบไดนามิกได้โดยใช้ dynamicDarkColorScheme() หรือ dynamicLightColorScheme() หากไม่ได้ ให้กลับไปใช้ColorSchemeสีอ่อนหรือสีเข้มเริ่มต้น
แทนที่โค้ดของฟังก์ชัน AppTheme ในไฟล์ Theme.kt ด้วยโค้ดด้านล่าง
Theme.kt
@Composable
fun AppTheme(
useDarkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
val context = LocalContext.current
val colors = when {
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) -> {
if (useDarkTheme) dynamicDarkColorScheme(context)
else dynamicLightColorScheme(context)
}
useDarkTheme -> DarkColors
else -> LightColors
}
MaterialTheme(
colorScheme = colors,
content = content
)
}

ธีมแบบไดนามิกที่นำมาจากวอลเปเปอร์ Android 13
เมื่อเรียกใช้แอปในตอนนี้ คุณควรเห็นการใช้การปรับแต่งตามธีมแบบไดนามิกโดยใช้วอลเปเปอร์เริ่มต้นของ Android 13
นอกจากนี้ คุณอาจต้องการให้แถบสถานะจัดรูปแบบแบบไดนามิกโดยขึ้นอยู่กับรูปแบบสีที่ใช้ในการกำหนดธีมแอป

แอปที่ไม่ได้ใช้สีแถบสถานะ (ซ้าย)
แอปที่ใช้สีแถบสถานะแล้ว (ขวา)
หากต้องการอัปเดตสีแถบสถานะตามสีหลักของธีม ให้เพิ่มสีแถบสถานะหลังจากการเลือกรูปแบบสีใน AppTheme ที่ใช้ร่วมกันได้
Theme.kt
@Composable
fun AppTheme(
useDarkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
// color scheme selection code
// Add primary status bar color from chosen color scheme.
val view = LocalView.current
if (!view.isInEditMode) {
SideEffect {
val window = (view.context as Activity).window
window.statusBarColor = colors.primary.toArgb()
WindowCompat
.getInsetsController(window, view)
.isAppearanceLightStatusBars = useDarkTheme
}
}
MaterialTheme(
colorScheme = colors,
content = content
)
}
เมื่อเรียกใช้แอป คุณควรเห็นแถบสถานะใช้ธีมสีหลัก นอกจากนี้ คุณยังลองใช้การกำหนดธีมแบบไดนามิกทั้งแบบสว่างและมืดได้โดยเปลี่ยนธีมมืดของระบบ

ธีมสว่าง (ซ้าย) และธีมมืด (ขวา) แบบไดนามิกที่ใช้กับวอลเปเปอร์เริ่มต้นของ Android 13
ที่ผ่านมา คุณได้ใช้สีกับแอปเพื่อปรับปรุงรูปลักษณ์ของแอป อย่างไรก็ตาม คุณจะเห็นว่าข้อความทั้งหมดในแอปมีขนาดเท่ากัน ดังนั้นตอนนี้คุณจึงเพิ่มการจัดรูปแบบข้อความลงในแอปได้แล้ว
6. การพิมพ์
Material Design 3 กำหนดขนาดตัวอักษร เราได้ลดความซับซ้อนของการตั้งชื่อและการจัดกลุ่มเป็นดังนี้ Display, Headline, Title, Body และ Label โดยมีขนาดใหญ่ กลาง และเล็กสำหรับแต่ละรายการ

มาตราส่วนประเภทวัสดุ 3
การกำหนดแบบตัวพิมพ์
Compose มีคลาส M3 Typography รวมถึงคลาส TextStyle และ font-related ที่มีอยู่แล้วเพื่อสร้างรูปแบบมาตราส่วนประเภท Material 3
ตัวสร้างการพิมพ์มีค่าเริ่มต้นสำหรับแต่ละสไตล์ คุณจึงละเว้นพารามิเตอร์ที่ไม่ต้องการปรับแต่งได้ ดูข้อมูลเพิ่มเติมได้ที่รูปแบบการพิมพ์และค่าเริ่มต้น
คุณจะใช้รูปแบบการพิมพ์ 5 รูปแบบในแอป ได้แก่ headlineSmall, titleLarge, bodyLarge, bodyMedium และ labelMedium โดยสไตล์เหล่านี้จะครอบคลุมทั้งหน้าจอหลักและหน้าจอรายละเอียด

หน้าจอที่แสดงการใช้ตัวอักษรของชื่อ ป้ายกำกับ และรูปแบบเนื้อหา
จากนั้นไปที่ui/themeแพ็กเกจ แล้วเปิด Type.kt เพิ่มโค้ดต่อไปนี้เพื่อใช้การติดตั้งใช้งานของคุณเองสำหรับรูปแบบข้อความบางอย่างแทนค่าเริ่มต้น
Type.kt
val typography = Typography(
headlineSmall = TextStyle(
fontWeight = FontWeight.SemiBold,
fontSize = 24.sp,
lineHeight = 32.sp,
letterSpacing = 0.sp
),
titleLarge = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 18.sp,
lineHeight = 28.sp,
letterSpacing = 0.sp
),
bodyLarge = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
lineHeight = 24.sp,
letterSpacing = 0.15.sp
),
bodyMedium = TextStyle(
fontWeight = FontWeight.Medium,
fontSize = 14.sp,
lineHeight = 20.sp,
letterSpacing = 0.25.sp
),
labelMedium = TextStyle(
fontWeight = FontWeight.SemiBold,
fontSize = 12.sp,
lineHeight = 16.sp,
letterSpacing = 0.5.sp
)
)
ตอนนี้คุณได้กำหนดแบบอักษรแล้ว หากต้องการเพิ่มลงในธีม ให้ส่งไปยัง MaterialTheme() Composable ภายใน AppTheme ดังนี้
Theme.kt
@Composable
fun AppTheme(
useDarkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable() () -> Unit
) {
// dynamic theming content
MaterialTheme(
colorScheme = colors,
typography = typography,
content = content
)
}
การทำงานกับตัวอักษร
เช่นเดียวกับสี คุณจะเข้าถึงรูปแบบการพิมพ์สำหรับธีมปัจจุบันได้โดยใช้ MaterialTheme.typography ซึ่งจะช่วยให้คุณมีอินสแตนซ์การพิมพ์เพื่อใช้การพิมพ์ที่กำหนดทั้งหมดใน Type.kt
Text(
text = "Hello M3 theming",
style = MaterialTheme.typography.titleLarge
)
Text(
text = "you are learning typography",
style = MaterialTheme.typography.bodyMedium
)
ผลิตภัณฑ์ของคุณอาจไม่จำเป็นต้องใช้รูปแบบเริ่มต้นทั้ง 15 รูปแบบจากขนาดตัวอักษรของ Material Design ใน Codelab นี้ เราเลือกขนาด 5 ขนาดและละเว้นขนาดอื่นๆ
เนื่องจากคุณไม่ได้ใช้การจัดรูปแบบข้อความกับ Composable Text() ข้อความทั้งหมดจึงกลับไปใช้ Typography.bodyLarge โดยค่าเริ่มต้น
การพิมพ์รายการหน้าแรก
จากนั้นใช้การจัดรูปแบบตัวอักษรกับReplyEmailListItemฟังก์ชันในui/components/ReplyEmailListItem.ktเพื่อสร้างความแตกต่างระหว่างชื่อและป้ายกำกับ
ReplyEmailListItem.kt
Text(
text = email.sender.firstName,
style = MaterialTheme.typography.labelMedium
)
Text(
text = email.createdAt,
style = MaterialTheme.typography.labelMedium
)
Text(
text = email.subject,
style = MaterialTheme.typography.titleLarge,
modifier = Modifier.padding(top = 12.dp, bottom = 8.dp),
)
Text(
text = email.body,
maxLines = 2,
style = MaterialTheme.typography.bodyLarge,
overflow = TextOverflow.Ellipsis
)

หน้าจอหลักที่ไม่ได้ใช้การจัดรูปแบบข้อความ (ซ้าย)
หน้าจอหลักที่ใช้การจัดรูปแบบข้อความ (ขวา)
การพิมพ์รายการรายละเอียด
ในทำนองเดียวกัน คุณจะเพิ่มการจัดรูปแบบตัวอักษรในหน้าจอรายละเอียดได้โดยการอัปเดตข้อความที่สามารถเขียนได้ทั้งหมดของ ReplyEmailThreadItem ใน ui/components/ReplyEmailThreadItem.kt:
ReplyEmailThreadItem.kt
Text(
text = email.sender.firstName,
style = MaterialTheme.typography.labelMedium
)
Text(
text = stringResource(id = R.string.twenty_mins_ago),
style = MaterialTheme.typography.labelMedium
)
Text(
text = email.subject,
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.padding(top = 12.dp, bottom = 8.dp),
)
Text(
text = email.body,
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onSurfaceVariant
)

หน้าจอรายละเอียดที่ไม่ได้ใช้การจัดรูปแบบข้อความ (ซ้าย)
หน้าจอรายละเอียดที่มีการใช้การพิมพ์ (ขวา)
การปรับแต่งตัวอักษร
ฟีเจอร์ช่วยเขียนช่วยให้คุณปรับแต่งสไตล์ข้อความหรือระบุแบบอักษรที่กำหนดเองได้ง่ายๆ คุณสามารถแก้ไข TextStyle เพื่อปรับแต่งประเภทแบบอักษร ชุดแบบอักษร ระยะห่างระหว่างตัวอักษร ฯลฯ
คุณจะเปลี่ยนรูปแบบข้อความในไฟล์ theme/Type.kt ซึ่งจะมีผลกับคอมโพเนนต์ทั้งหมดที่ใช้รูปแบบนั้น
อัปเดต fontWeight เป็น SemiBold และ lineHeight เป็น 32.sp สำหรับ titleLarge ซึ่งใช้สำหรับเรื่องในรายการ ซึ่งจะเน้นที่ตัวแบบมากขึ้นและแยกตัวแบบออกจากพื้นหลังอย่างชัดเจน
Type.kt
...
titleLarge = TextStyle(
fontWeight = FontWeight.SemiBold,
fontSize = 18.sp,
lineHeight = 32.sp,
letterSpacing = 0.0.sp
),
...

ใช้การจัดรูปแบบตัวอักษรที่กำหนดเองกับข้อความเรื่อง
7. รูปร่าง
พื้นผิวของ Material จะแสดงในรูปทรงต่างๆ ได้ รูปร่างดึงดูดความสนใจ ระบุคอมโพเนนต์ สื่อสารสถานะ และแสดงแบรนด์
การกำหนดรูปทรง
Compose มีคลาส Shapes พร้อมพารามิเตอร์ที่ขยายเพื่อใช้รูปร่าง M3 ใหม่ สเกลรูปร่าง M3 ซึ่งคล้ายกับสเกลประเภทช่วยให้แสดงรูปร่างได้หลากหลายใน UI
รูปร่างมีหลายขนาดในมาตราส่วนรูปร่าง ดังนี้
- เล็กพิเศษ
- เล็ก
- ปานกลาง
- ใหญ่
- ใหญ่พิเศษ
โดยค่าเริ่มต้น รูปร่างแต่ละรูปร่างจะมีค่าเริ่มต้นที่สามารถลบล้างได้ สำหรับแอป คุณจะใช้รูปร่างขนาดกลางเพื่อแก้ไขรายการ แต่ก็ประกาศรูปร่างอื่นๆ ได้เช่นกัน สร้างไฟล์ใหม่ชื่อ Shape.kt ในแพ็กเกจ ui/theme แล้วเพิ่มโค้ดสำหรับรูปร่าง
Shape.kt
package com.example.reply.ui.theme
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Shapes
import androidx.compose.ui.unit.dp
val shapes = Shapes(
extraSmall = RoundedCornerShape(4.dp),
small = RoundedCornerShape(8.dp),
medium = RoundedCornerShape(16.dp),
large = RoundedCornerShape(24.dp),
extraLarge = RoundedCornerShape(32.dp)
)
เมื่อกำหนด shapes แล้ว ให้ส่งไปยัง MaterialTheme ของ M3 เช่นเดียวกับที่ทำกับสีและตัวอักษร
Theme.kt
@Composable
fun AppTheme(
useDarkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable() () -> Unit
) {
// dynamic theming content
MaterialTheme(
colorScheme = colors,
typography = typography,
shapes = shapes
content = content
)
}
การทำงานกับรูปร่าง
เช่นเดียวกับสีและตัวอักษร คุณสามารถใช้รูปร่างกับคอมโพเนนต์ Material ได้โดยใช้ MaterialTheme.shape ซึ่งจะให้อินสแตนซ์ Shape เพื่อเข้าถึงรูปร่าง Material
คอมโพเนนต์ Material จำนวนมากมีรูปร่างเริ่มต้นที่ใช้กับคอมโพเนนต์อยู่แล้ว แต่คุณสามารถระบุและใช้รูปร่างของคุณเองกับคอมโพเนนต์ผ่านช่องที่มีอยู่ได้
Card(shape = MaterialTheme.shapes.medium) { /* card content */ }
FloatingActionButton(shape = MaterialTheme.shapes.large) { /* fab content */}
*การแมปคอมโพเนนต์ของ Material โดยใช้รูปร่างประเภทต่างๆ*
คุณดูการแมปรูปร่างสำหรับคอมโพเนนต์ทั้งหมดได้ในเอกสารประกอบเกี่ยวกับรูปร่าง
นอกจากนี้ยังมีรูปร่างอื่นๆ อีก 2 แบบที่ใช้ได้ ได้แก่ RectangleShape และ CircleShape ซึ่งเป็นส่วนหนึ่งของ Compose รูปสี่เหลี่ยมผืนผ้าไม่มีรัศมีเส้นขอบ และรูปวงกลมแสดงขอบวงกลมเต็ม
นอกจากนี้ คุณยังใช้รูปร่างกับคอมโพเนนต์ได้โดยใช้ Modifiers ที่ใช้รูปร่าง เช่น Modifier.clip, Modifier.background และ Modifier.border
รูปร่างของแถบแอป
เราต้องการให้แถบแอปมีพื้นหลังเป็นมุมโค้ง

TopAppBar กำลังใช้ Row ที่มีสีพื้นหลัง หากต้องการให้พื้นหลังมีมุมโค้งมน ให้กำหนดรูปร่างของพื้นหลังโดยส่ง CircleShape ไปยังตัวแก้ไขพื้นหลัง
ReplyAppBars.kt
@Composable
fun ReplySearchBar(modifier: Modifier = Modifier) {
Row(
modifier = modifier
.fillMaxWidth()
.padding(16.dp)
.background(
MaterialTheme.colorScheme.background,
CircleShape
),
verticalAlignment = Alignment.CenterVertically
) {
// Search bar content
}
}

รูปร่างของรายการรายละเอียด
ในหน้าจอหลัก คุณกำลังใช้บัตรที่ใช้ Shape.Medium โดยค่าเริ่มต้น แต่สำหรับหน้าดีเทล คุณใช้คอลัมน์ที่มีสีพื้นหลังแทน หากต้องการให้รายการมีลักษณะที่สม่ำเสมอ ให้ใช้รูปร่างขนาดกลางกับรายการ

คอลัมน์รายการแบบละเอียดที่ไม่มีรูปร่างในรายการ (ซ้าย) และมีรูปร่างปานกลางในรายการ (ขวา)
ReplyEmailThreadItem.kt
@Composable
fun ReplyEmailThreadItem(
email: Email,
modifier: Modifier = Modifier
) {
Column(
modifier = modifier
.fillMaxWidth()
.padding(8.dp)
.background(
MaterialTheme.colorScheme.background,
MaterialTheme.shapes.medium
)
.padding(16.dp)
) {
// List item content
}
}
ตอนนี้การเรียกใช้แอปจะแสดงรายการหน้าจอแบบละเอียดที่มีรูปร่างเป็น medium
8. การเน้น
การเน้นใน UI ช่วยให้คุณไฮไลต์เนื้อหาบางอย่างเหนือเนื้อหาอื่นๆ ได้ เช่น เมื่อต้องการแยกความแตกต่างระหว่างชื่อกับคำบรรยาย การเน้นใน M3 ใช้สีที่แตกต่างกันและการผสมสี คุณเน้นข้อความได้ 2 วิธี ดังนี้
- การใช้สีพื้นผิว สีพื้นผิวแบบต่างๆ และสีพื้นหลังควบคู่ไปกับสีบนพื้นผิวและสีบนพื้นผิวแบบต่างๆ จากระบบสี M3 ที่ขยาย
เช่น คุณใช้ surface กับ on-surface-variant และใช้ surface-variant กับ on-surface เพื่อให้ระดับการเน้นที่แตกต่างกันได้
นอกจากนี้ คุณยังใช้สีพื้นผิวที่แตกต่างกันกับสีเฉพาะจุดเพื่อให้เน้นน้อยกว่าสี On-Color ได้ แต่ยังคงเข้าถึงได้และเป็นไปตามอัตราส่วนคอนทราสต์

บทบาทของสีพื้นผิว พื้นหลัง และสีพื้นผิวตัวแปร
- การใช้ความหนาของแบบอักษรที่แตกต่างกันสำหรับข้อความ ดังที่เห็นในส่วนการจัดรูปแบบข้อความ คุณสามารถระบุน้ำหนักที่กำหนดเองให้กับขนาดตัวอักษรเพื่อเน้นข้อความต่างๆ ได้
จากนั้นอัปเดต ReplyEmailListItem.kt เพื่อให้ความแตกต่างของความสำคัญโดยใช้รูปแบบพื้นผิว โดยค่าเริ่มต้น เนื้อหาของการ์ดจะใช้สีเนื้อหาเริ่มต้นตามพื้นหลัง
คุณจะอัปเดตสีของ Composable ของข้อความเวลาและข้อความเนื้อหาเป็น onSurfaceVariant ซึ่งจะลดความสำคัญของข้อความเมื่อเทียบกับ onContainerColors ซึ่งจะใช้กับข้อความเรื่องและชื่อที่คอมโพสได้โดยค่าเริ่มต้น

ข้อความเวลาและเนื้อหาที่มีการเน้นเหมือนกันเมื่อเทียบกับเรื่องและชื่อ (ซ้าย)
เวลาและเนื้อหาที่มีการเน้นน้อยลงเมื่อเทียบกับเรื่องและชื่อ (ขวา)
ReplyEmailListItem.kt
Text(
text = email.createdAt,
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Text(
text = email.body,
maxLines = 2,
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onSurfaceVariant
overflow = TextOverflow.Ellipsis
)
สำหรับการ์ดอีเมลสำคัญที่มีพื้นหลัง secondaryContainer สีข้อความทั้งหมดจะเป็นสี onSecondaryContainer โดยค่าเริ่มต้น สำหรับอีเมลอื่นๆ พื้นหลังจะเป็น surfaceVariant, ดังนั้นข้อความทั้งหมดจึงมีสีเริ่มต้นเป็น onSurfaceVariant
9. ขอแสดงความยินดี
ยินดีด้วย คุณทำ Codelab นี้เสร็จเรียบร้อยแล้ว คุณได้ใช้การจัดธีม Material กับ Compose โดยใช้สี แบบอักษร และรูปร่างพร้อมกับสีแบบไดนามิกเพื่อจัดธีมแอปพลิเคชันและมอบประสบการณ์การใช้งานที่ปรับเปลี่ยนในแบบของคุณ

สิ้นสุดผลลัพธ์การจัดธีมด้วยสีแบบไดนามิกและธีมสีที่ใช้
ขั้นตอนถัดไป
ดู Codelab อื่นๆ ในเส้นทาง Compose
อ่านเพิ่มเติม
- คู่มือการกำหนดธีม Compose
- การกำหนดธีม Material สำหรับ Compose
แอปตัวอย่าง
- แอป Reply sample ที่มีธีม Material 3 แบบเต็ม
- JetChat แสดงการกำหนดธีมแบบไดนามิก