1. ก่อนเริ่มต้น
ในโค้ดแล็บนี้ คุณจะอัปเดตแอปเริ่มต้น ซึ่งเป็นแอปเครื่องคำนวณทิป เพื่อใช้ฟีเจอร์ใหม่ใน 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> | สีของไอคอนและข้อความที่ปรากฏบนสีพื้น |
คอนเทนเนอร์ <สีพื้นฐาน> | ได้มาจากสีพื้นฐาน ใช้สำหรับปุ่ม กล่องโต้ตอบ ฯลฯ |
on<base color>Container | สีของไอคอนและข้อความในคอนเทนเนอร์ |
ตัวอย่างเช่น ปุ่มลอยที่มีการจัดรูปแบบเริ่มต้นใน Material 3 จะใช้ Primary เป็นสีพื้นฐาน ดังนั้นจึงใช้ primaryContainer เป็นสีพื้นหลังของปุ่ม และใช้ onPrimaryContainer เป็นเนื้อหาของปุ่ม
เมื่อปรับแต่งธีมด้วยตนเอง คุณควรตรวจสอบอย่างน้อยว่าon<base color>แอตทริบิวต์สำหรับสีฐานทุกสีที่คุณเปลี่ยนยังคงอ่านได้
แนวทางปฏิบัติแนะนำคือการปรับบทบาททั้งหมดในกลุ่มสีพร้อมกันเพื่อให้แน่ใจว่าไม่มีสิ่งประดิษฐ์จากฐานผ่านไปยังแอป
โดยทั่วไปแล้ว สีพื้นหลังและสีฐานของ Surface จะมี 2 บทบาท ได้แก่ สีฐานเองและ on<base color> สำหรับไอคอนหรือข้อความที่ปรากฏบนสีฐาน
5. การสร้างธีม Material 3 ด้วย Material Theme Builder
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
รีสตาร์ทแอป แล้วแอปจะดูเหมือนเดิมแทบทุกประการ การเปลี่ยนแปลงที่สำคัญอย่างหนึ่งคือ Switch และ RadioButtons ซึ่งตอนนี้สถานะที่เลือกจะใช้ธีมที่มีโทนสีจากสีหลักเทียบกับสีรอง ในแอปพลิเคชันขนาดใหญ่ คุณอาจต้องกลับไปดูการออกแบบบางอย่าง

<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 เป็นแบบไดนามิกได้ด้วยการเพิ่มเล็กๆ น้อยๆ
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. สรุป
ในโค้ดแล็บนี้ คุณได้ทำสิ่งต่อไปนี้
- เพิ่มทรัพยากร Dependency เพื่ออัปเกรดธีมเป็น Material 3
- ทำความเข้าใจกลุ่มสีและบทบาทใหม่
- ทําความเข้าใจวิธีย้ายข้อมูลจากธีมแบบคงที่ไปยังสีแบบเปลี่ยนอัตโนมัติ
- ทำความเข้าใจวิธีใช้การวางซ้อนธีมและใช้สีแบบไดนามิกสำหรับแอตทริบิวต์ธีมที่กำหนดเอง