1. ก่อนเริ่มต้น
ใน Codelab นี้ คุณจะอัปเดตแอปเริ่มต้น ซึ่งเป็นแอปเครื่องคำนวณทิป ให้ใช้ฟีเจอร์ใหม่ใน Material Design 3 ซึ่งช่วยให้สามารถกำหนดธีมอินเทอร์เฟซผู้ใช้ของแอปพลิเคชันแบบไดนามิกตามวอลเปเปอร์ของผู้ใช้ ด้านล่างนี้คือภาพหน้าจอ 2 ภาพของแอปพลิเคชันที่ใช้สีแบบไดนามิก นอกจากนี้ คุณยังจะได้ดูสถานการณ์เพิ่มเติมบางอย่างที่ช่วยให้คุณควบคุมวิธีใช้สีได้ด้วย
ข้อกำหนดเบื้องต้น
นักพัฒนาแอปควร
- คุ้นเคยกับแนวคิดการกำหนดธีมพื้นฐานใน Android
- คุ้นเคยกับการแก้ไขธีมของแอป
สิ่งที่คุณจะได้เรียนรู้
- วิธีแยกความแตกต่างระหว่างคอมโพเนนต์ Material ที่มีอยู่กับธีม Material 3
- วิธีอัปเดตธีมเป็น Material 3
- วิธีสร้างธีมโดยใช้เครื่องมือของเราและนำไปใช้
- ความสัมพันธ์ของแอตทริบิวต์ธีม
สิ่งที่คุณต้องมี
- คอมพิวเตอร์ที่ติดตั้ง Android Studio
- รหัสสำหรับแอปพลิเคชัน Tip Time https://github.com/google-developer-training/android-basics-kotlin-tip-calculator-app-solution
2. ภาพรวมแอปเริ่มต้น
แอป Tip Time เป็นแอปเครื่องคำนวณทิปที่มีตัวเลือกในการปรับแต่งทิป ซึ่งเป็นหนึ่งในตัวอย่างแอปจากหลักสูตรการฝึกอบรมข้อมูลพื้นฐานเกี่ยวกับ Android ใน Kotlin

3. การอัปเดตทรัพยากร Dependency ของ Gradle
ก่อนที่เราจะอัปเดตธีมจริงและใช้สีแบบไดนามิก คุณต้องทำการเปลี่ยนแปลงบางอย่างในไฟล์ build.gradle สำหรับแอปพลิเคชันของคุณ
ในส่วนทรัพยากร Dependency ให้ตรวจสอบว่าไลบรารี Material เป็นเวอร์ชัน 1.5.0-alpha04 ขึ้นไป
dependencies {
// ...
implementation 'com.google.android.material:material:<version>'
}
ในส่วน Android ให้เปลี่ยน compileSdkVersion และ targetSdkVersion
ถึง 31 หรือใหม่กว่า
android {
compileSdkVersion 31
// ...
defaultConfig {
// ...
targetSdkVersion 31
}
}
คำสั่งเหล่านี้ถือว่าแอปมีทรัพยากร Dependency ที่ค่อนข้างใหม่ สำหรับแอปที่ยังไม่ได้ใช้ Material หรือใช้เวอร์ชันที่เก่ากว่า โปรดดูวิธีการในเอกสารประกอบการเริ่มต้นใช้งานของคอมโพเนนต์ Material Design สำหรับ Android
ไม่ว่าคุณจะสร้างธีมไว้ที่ใด ให้เปลี่ยนการอ้างอิงของ Theme.MaterialComponents.* เป็น Theme.Material3.* บางสไตล์ยังไม่มีสไตล์ใหม่ในเนมสเปซ Material3 แต่คอมโพเนนต์ส่วนใหญ่จะยังคงรับช่วงสไตล์ใหม่เมื่ออัปเดตธีมหลักเป็น Theme.Material3.* เราจะเห็นด้านล่างว่าตอนนี้ปุ่มต่างๆ ใช้ธีมใหม่แบบโค้งมนแล้ว
ในไฟล์ธีมด้านล่าง สิ่งเดียวที่เปลี่ยนแปลงคือธีมหลัก เราจะแทนที่ธีมนี้ทั้งหมดในอีกสักครู่ แอตทริบิวต์สีบางอย่างเลิกใช้งานแล้ว และสไตล์ที่กำหนดเองบางอย่างที่เราสร้างขึ้นตอนนี้เป็นมาตรฐานใน Material3 แต่เราต้องการให้คุณมี
themes.xml
<style name="Theme.TipTime" parent="Theme.Material3.Light">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/green</item>
<item name="colorPrimaryVariant">@color/green_dark</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/blue</item>
<item name="colorSecondaryVariant">@color/blue_dark</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- For text input fields -->
<item name="textInputStyle">@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox</item>
<!-- For radio buttons -->
<item name="radioButtonStyle">@style/Widget.TipTime.CompoundButton.RadioButton</item>
<!-- For switches -->
<item name="switchStyle">@style/Widget.TipTime.CompoundButton.Switch</item>
</style>

4. ทำความเข้าใจการกำหนดธีมสีและบทบาทของสี
ระบบสี Material 3 ใช้แนวทางที่มีการจัดระเบียบเพื่อใช้สีกับ UI แอตทริบิวต์จำนวนหนึ่งจาก Theme.AppCompat ยังคงใช้งานอยู่ อย่างไรก็ตาม มีการเพิ่มแอตทริบิวต์เพิ่มเติมใน Theme.MaterialComponents.* และเพิ่มอีกใน Theme.Material3.* ดังนั้นคุณจึงควรตรวจสอบทุกหน้าจอของแอปเพื่อให้แน่ใจว่าไม่มีพร็อพเพอร์ตี้ที่ไม่ได้ใช้หลุดมาจากธีมฐาน
ทำความเข้าใจบทบาทของสี
ธีม Material 3 มีแอตทริบิวต์ที่เกี่ยวข้องกับสีมากกว่า 20 รายการ แม้ว่าในตอนแรกอาจดูน่ากลัว แต่จริงๆ แล้วมีสีหลักเพียงไม่กี่สีที่ใช้ร่วมกับบทบาทสีเดียวกัน 4-5 สีเพื่อสร้างสีอนุพันธ์
กลุ่มสีเหล่านั้น ได้แก่
- Primary สีหลักของแอป
- รอง สีรองของแอป
- สีตติยภูมิ ซึ่งเป็นสีที่ 3 ที่เป็นสีเสริมของสีปฐมภูมิและสีทุติยภูมิ
- ข้อผิดพลาด ใช้สำหรับข้อความและกล่องโต้ตอบแสดงข้อผิดพลาด
- ฉากหลัง
- Surface, SurfaceVariant, Surface Inverse
บทบาทสำหรับ Primary, Secondary, Tertiary และ Error มีดังนี้
<สีพื้นฐาน> | สีฐาน |
on<base color> | สีของไอคอนและข้อความที่ปรากฏบนสีพื้น |
คอนเทนเนอร์ <สีพื้นฐาน> | ได้มาจากสีพื้นฐาน ใช้กับปุ่ม กล่องโต้ตอบ ฯลฯ |
ใน<base color>Container | สีของไอคอนและข้อความในคอนเทนเนอร์ |
ตัวอย่างเช่น ปุ่มการทำงานแบบลอยที่มีการจัดรูปแบบเริ่มต้นใน Material 3 จะใช้ Primary เป็นสีพื้นฐาน ดังนั้นจึงใช้ primaryContainer เป็นสีพื้นหลังของปุ่ม และใช้ onPrimaryContainer เป็นเนื้อหาของปุ่ม
เมื่อปรับแต่งธีมด้วยตนเอง คุณควรตรวจสอบอย่างน้อยว่าon<base color>แอตทริบิวต์สำหรับสีฐานทุกสีที่คุณเปลี่ยนยังคงอ่านได้
แนวทางปฏิบัติแนะนำคือการปรับบทบาททั้งหมดในกลุ่มสีพร้อมกันเพื่อให้แน่ใจว่าไม่มีสิ่งประดิษฐ์จากฐานผ่านไปยังแอป
โดยทั่วไปแล้ว สีพื้นหลังและสีฐานของ Surface จะมี 2 บทบาท ได้แก่ สีฐานเองและ on<base color> สำหรับไอคอนหรือข้อความที่ปรากฏบนสีฐาน
5. การสร้างธีม Material 3 ด้วยเครื่องมือสร้างธีม Material
Material Theme Builder ช่วยให้สร้างรูปแบบสีที่กำหนดเอง ใช้การส่งออกโค้ดในตัวเพื่อย้ายข้อมูลไปยังระบบสี M3 และใช้ประโยชน์จากสีแบบไดนามิกได้อย่างง่ายดาย ดูข้อมูลเพิ่มเติม material.io/material-theme-builder
ธีมแอป Tip Time มีหลายสไตล์สำหรับคอมโพเนนต์ แต่สไตล์ส่วนใหญ่เป็นค่าเริ่มต้นในธีม Material 3 สีหลัก 2 สีที่เราต้องกังวลคือสีหลักและสีรอง
ซึ่งตรงกับสีหลักสีเขียว (#1B5E20) และสีรองสีน้ำเงิน (#0288D1)
คุณสามารถป้อนสีเหล่านั้นลงใน Material Theme Builder และส่งออกธีมแบบเต็มได้ (สมมติว่ามีลิงก์ไปยังภาพรวมแบบเต็มที่อื่น)
โปรดทราบว่าสีที่คุณป้อนอาจมีการปรับโทนเพื่อให้เข้ากับอัลกอริทึมการสร้างสี และเพื่อให้มั่นใจว่าสีจะเสริมกันและอ่านได้
ด้านล่างนี้คือชุดย่อยของค่าที่สร้างขึ้นเมื่อคุณป้อนสีแบบกำหนดเอง

6. การทำงานกับไฟล์ส่งออกของ Material Theme Builder
ไฟล์เก็บถาวรของการส่งออกจะมีไดเรกทอรี values และ values-night/ พร้อมไฟล์ themes.xml ของตัวเอง ซึ่งสอดคล้องกับธีมสว่างและธีมมืด สีทั้งหมดกำหนดไว้ใน values/colors.xml

คุณสามารถคัดลอกไฟล์ได้ตามเดิม แต่จะต้องเปลี่ยนชื่อธีมใน AndroidManifest.xml หรือในไฟล์ธีมให้ตรงกัน ชื่อเริ่มต้นจากเครื่องมือคือ AppTheme
รีสตาร์ทแอป แล้วแอปจะดูเหมือนเดิมแทบทุกประการ การเปลี่ยนแปลงที่สำคัญอย่างหนึ่งคือสวิตช์และ RadioButton ซึ่งตอนนี้สถานะที่เลือกจะใช้ธีมที่มีเฉดสีจากสีหลักเทียบกับสีรอง ในแอปพลิเคชันขนาดใหญ่ คุณอาจต้องกลับไปดูการออกแบบบางอย่าง

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.tiptime">
<application ...>
<activity android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
7. การเพิ่มสีแบบไดนามิก
เมื่อใช้ธีม Material 3 ที่เหมาะสม เราจะทำให้ UI เป็นแบบไดนามิกได้ด้วยการเพิ่มเล็กๆ น้อยๆ 2-3 อย่าง
API สีแบบไดนามิกช่วยให้คุณใช้สีแบบไดนามิกกับทุกกิจกรรมได้
ในแอป กิจกรรมแต่ละรายการ หรือไปยัง View หรือ Fragment แต่ละรายการ สำหรับ
แอปนี้ เราจะใช้สีแบบไดนามิกทั่วโลก
สร้างไฟล์คลาสแอปพลิเคชัน
class TipTimeApplication: Application() {
override fun onCreate() {
// Apply dynamic color
DynamicColors.applyToActivitiesIfAvailable(this)
}
}
เราต้องอ้างอิงไฟล์ที่สร้างขึ้นใหม่นี้ใน Android Manifest ดังนี้
AndroidManifest.xml
< application android name=".TipTimeApplication
<!--- Other existing attributes –>
</application >
ในระบบ Android 12 ขึ้นไป ระบบจะตรวจสอบวอลเปเปอร์ของผู้ใช้สำหรับรูปแบบเริ่มต้นเพื่อสร้างจานสีโทนต่างๆ ระบบจะใช้ค่าจากจานสีเหล่านี้เพื่อสร้าง ThemeOverlay
คลาส DynamicColors จะลงทะเบียน ActivityLifecycleCallbacks ที่สกัดกั้นใน ActivityPreCreated เพื่อใช้การวางซ้อนธีมแบบไดนามิกที่ระบบสร้างขึ้น หรือธีมที่คุณระบุ

8. การใช้การวางซ้อนธีมที่กำหนดเอง
เครื่องมือของเราสามารถส่งออกภาพซ้อนทับของธีมได้ แต่คุณก็สร้างด้วยตนเองได้เช่นกันหากจะลบล้างแอตทริบิวต์เพียงไม่กี่รายการ
การวางซ้อนธีมมีไว้เพื่อใช้ร่วมกับธีมอื่น และจะให้เฉพาะค่าที่จะเปลี่ยนแปลงบนธีมฐานเท่านั้น
สมมติว่าด้วยเหตุผลบางอย่าง เช่น การสร้างแบรนด์ เราต้องการให้โทนสีหลักเป็นเฉดสีแดง เราทำได้ด้วยไฟล์และแอตทริบิวต์ต่อไปนี้
colors.xml
<resources>
<color name="overlay_light_primary">#9C4146</color>
<color name="overlay_light_onPrimary">#FFFFFF</color>
<color name= "overlay_light_primaryContainer">#FFDADB</color>
<color name="overlay_light_onPrimaryContainer">#400008</color>
</resources >
themes_overlays.xml
<style name="AppTheme.Overlay" parent="ThemeOverlay.Material3.DynamicColors.Light">
<item name="colorPrimary">@color/overlay_light_primary</item>
<item name="colorOnPrimary">@color/overlay_light_onPrimary</item>
<item name="colorPrimaryContainer">@color/overlay_light_primaryContainer</item>
<item name="colorOnPrimaryContainer">@color/overlay_light_onPrimaryContainer<item>
</style>
สําหรับโค้ดข้างต้น Android 12 จะใช้ธีมสว่างแบบไดนามิกและวางการเปลี่ยนแปลงของคุณไว้ด้านบน หรือจะใช้ ThemeOverlay ที่ถูกต้องเป็นองค์ประกอบหลักก็ได้ ซึ่งรวมถึงองค์ประกอบใดองค์ประกอบหนึ่งต่อไปนี้
ThemeOverlay.Material3.Light
ThemeOverlay.Material3.Dark
ThemeOverlay.Material3.DayNight ThemeOverlay.Material3.DynamicColors.Dark
ThemeOverlay.Material3.DynamicColors.DayNight
หากต้องการใช้การวางซ้อนธีมนี้แทนค่าเริ่มต้นของ Material ให้เปลี่ยนการเรียกใช้เป็น DynamicColors.applyToActivitiesIfAvailable ดังนี้
DynamicColors.applyToActivitiesIfAvailable(this, R.style.AppTheme_Overlay)

9. การเพิ่มสีแบบไดนามิกลงในแอตทริบิวต์ที่กำหนดเอง
ที่ผ่านมาเราได้ลบล้างคุณสมบัติที่มีอยู่ในธีม Material 3 อยู่แล้ว นอกจากนี้ ยังมีอีกกรณีที่อาจเกิดขึ้นในสีแบบไดนามิก ซึ่งเราอาจมีแอตทริบิวต์ที่กำหนดเองอย่างน้อย 1 รายการที่ต้องจัดสรร
เมื่อแอปเลือกใช้สีแบบไดนามิก แอปจะมีสิทธิ์เข้าถึงชุดสี 5 ชุด ได้แก่ ชุดสีเน้น 3 ชุดและชุดสีกลาง 2 ชุดที่มีบทบาทโดยประมาณดังนี้
system_accent1 | โทนสีหลัก |
system_accent2 | โทนสีรอง |
system_accent3 | โทนสีลำดับที่ 3 |
system_neutral1 | พื้นหลังและพื้นผิวที่เป็นกลาง |
system_neutral2 | พื้นผิวและเส้นขอบที่เป็นกลาง |
แต่ละจานสีจะมีจำนวนขั้นโทนสีตั้งแต่สีขาว
เป็นสีดำ: 0, 10, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000
เมื่อออกแบบ UI สำหรับสีแบบไดนามิก คุณควรคิดถึงสีที่เฉพาะเจาะจงให้น้อยลง และคิดถึงความสัมพันธ์ของโทนสีและความสว่างของคอมโพเนนต์นั้นกับคอมโพเนนต์อื่นๆ ในระบบการออกแบบให้มากขึ้น
สมมติว่าคุณต้องการให้ไอคอนใช้ธีมโดยใช้จานสีเน้นรอง และคุณได้เพิ่มแอตทริบิวต์เพื่อปรับสีไอคอนด้วยรายการต่อไปนี้ใน attrs.xml
attrs.xml
<resources>
<attr name="iconColor" format="color" />
</resources>
การซ้อนทับธีมอาจมีลักษณะดังนี้
<style name="AppTheme.Overlay" parent="ThemeOverlay.Material3.DynamicColors.DayNight">
<item name="iconColor">@android:color/system_accent2_600</item>
</style>
เมื่อคุณติดตั้งแอปอีกครั้งและเปลี่ยนวอลเปเปอร์ แอปจะเลือกใช้ชุดสีรองนั้น


จานสีเหล่านี้ใช้ได้กับ Android 12 (API 31) โดยเฉพาะ ดังนั้นคุณจะต้องวางไฟล์ที่เกี่ยวข้องในโฟลเดอร์ที่มีคำต่อท้าย -v31 เว้นแต่แอปของคุณจะมี SDK ขั้นต่ำที่ตั้งค่าเป็น 31 ขึ้นไป
10. สรุป
ใน Codelab นี้ คุณได้ทำสิ่งต่อไปนี้
- เพิ่มทรัพยากร Dependency เพื่ออัปเกรดธีมเป็น Material 3
- ทำความเข้าใจกลุ่มสีและบทบาทใหม่
- ทําความเข้าใจวิธีย้ายข้อมูลจากธีมแบบคงที่ไปยังสีแบบเปลี่ยนอัตโนมัติ
- ทำความเข้าใจวิธีใช้การวางซ้อนธีมและใช้สีแบบไดนามิกสำหรับแอตทริบิวต์ธีมที่กำหนดเอง