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
เราขอแนะนำให้คุณเริ่มต้นด้วยโค้ดในสาขาหลักและทำตาม 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
เมื่อเพิ่มสีหลักใน 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 Composable ภายใน 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 ซึ่งเป็นพื้นหลังที่ใช้ได้กับคอมโพเนนต์ 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, บรรทัดแรก, ชื่อ, ข้อความ และป้ายกำกับ โดยมีขนาดใหญ่ กลาง และเล็กสำหรับแต่ละรายการ

มาตราส่วนประเภทวัสดุ 3
การกำหนดแบบตัวพิมพ์
Compose มีคลาส Typography ของ M3 รวมถึงคลาส 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 ในโค้ดแล็บนี้ เราจะเลือก 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 ที่ขยาย
เช่น คุณสามารถใช้ "พื้นผิว" กับ "ตัวแปรบนพื้นผิว" และใช้ "ตัวแปรพื้นผิว" กับ "บนพื้นผิว" เพื่อให้ระดับการเน้นที่แตกต่างกัน
นอกจากนี้ คุณยังใช้สีพื้นผิวที่แตกต่างกันกับสีเฉพาะจุดเพื่อให้เน้นน้อยกว่าสี 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 แสดงการกำหนดธีมแบบไดนามิก