1. Trước khi bắt đầu
Trong lớp học lập trình này, bạn sẽ cập nhật ứng dụng khởi đầu (một ứng dụng tính tiền boa) để sử dụng các tính năng mới trong Material Design 3, cho phép giao diện người dùng của ứng dụng được thiết kế theo chủ đề một cách linh hoạt dựa trên hình nền của người dùng. Dưới đây là một số ảnh chụp màn hình của ứng dụng đã áp dụng màu động. Bạn cũng sẽ xem xét một số trường hợp bổ sung cho phép bạn kiểm soát cách áp dụng màu sắc.
Điều kiện tiên quyết
Nhà phát triển nên
- Quen thuộc với các khái niệm cơ bản về việc tạo giao diện trong Android
- Tự tin sửa đổi giao diện của ứng dụng
Kiến thức bạn sẽ học được
- Cách phân biệt giữa Thành phần Material hiện có và giao diện Material 3
- Cách cập nhật một giao diện thành Material 3
- Cách tạo và áp dụng các chủ đề bằng công cụ của chúng tôi
- Mối quan hệ giữa các thuộc tính giao diện
Bạn cần có
- Một máy tính đã cài đặt Android Studio.
- Mã cho ứng dụng Tip Time. https://github.com/google-developer-training/android-basics-kotlin-tip-calculator-app-solution
2. Tổng quan về ứng dụng khởi đầu
Ứng dụng Tip Time là một ứng dụng tính tiền boa cho phép tuỳ chỉnh số tiền boa. Đây là một trong những ứng dụng mẫu trong khoá đào tạo Kiến thức cơ bản về cách tạo ứng dụng Android bằng Kotlin.

3. Cập nhật phần phụ thuộc Gradle
Trước khi cập nhật chủ đề thực tế và áp dụng màu động, bạn cần thực hiện một số thay đổi trong tệp build.gradle cho ứng dụng của mình.
Trong mục phần phụ thuộc, hãy đảm bảo rằng thư viện material là 1.5.0-alpha04 trở lên:
dependencies {
// ...
implementation 'com.google.android.material:material:<version>'
}
Trong phần android, hãy thay đổi compileSdkVersion và targetSdkVersion
đến 31 hoặc muộn hơn:
android {
compileSdkVersion 31
// ...
defaultConfig {
// ...
targetSdkVersion 31
}
}
Hướng dẫn này giả định một ứng dụng có các phần phụ thuộc tương đối gần đây. Đối với một ứng dụng chưa sử dụng Material hoặc một phiên bản cũ hơn, vui lòng xem hướng dẫn trong tài liệu Bắt đầu của Các thành phần Material Design cho Android.
Bất cứ nơi nào bạn đã tạo giao diện, hãy thay đổi các tham chiếu của Theme.MaterialComponents.* thành Theme.Material3.*. Một số kiểu chưa có kiểu mới trong không gian tên Material3, nhưng hầu hết các thành phần vẫn sẽ kế thừa kiểu mới sau khi giao diện gốc được cập nhật thành Theme.Material3.*. Chúng ta có thể thấy bên dưới rằng các nút hiện có giao diện bo tròn mới.
Trong tệp giao diện dưới đây, điều duy nhất đã thay đổi là giao diện mẹ. Chúng ta sẽ thay thế hoàn toàn chủ đề này trong giây lát. Một số thuộc tính màu đã lỗi thời và một số kiểu tuỳ chỉnh mà chúng tôi đã tạo hiện là tiêu chuẩn trong Material3, nhưng chúng tôi muốn bạn có
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. Tìm hiểu về giao diện màu và vai trò của màu sắc
Hệ thống màu Material 3 sử dụng một phương pháp có tổ chức để áp dụng màu sắc cho giao diện người dùng. Một số thuộc tính trong Theme.AppCompat vẫn đang được sử dụng. Tuy nhiên, nhiều thuộc tính đã được thêm vào Theme.MaterialComponents.* và thậm chí còn nhiều hơn trong Theme.Material3.*, vì vậy, bạn cần kiểm tra tất cả các màn hình của ứng dụng để đảm bảo không có thuộc tính chưa triển khai nào bị rò rỉ từ giao diện cơ bản.
Tìm hiểu về vai trò của màu sắc
Có hơn 20 thuộc tính liên quan đến màu sắc trong giao diện Material 3. Thoạt nhìn, việc này có vẻ sẽ rất khó khăn, nhưng thực ra chỉ có một vài màu chính kết hợp với 4 – 5 vai trò màu sắc giống nhau để tạo ra các màu phái sinh.
Các nhóm màu đó là:
- Primary (Chính), màu chính của ứng dụng
- Màu phụ, màu phụ của ứng dụng
- Màu thứ ba, là màu thứ ba bổ sung cho màu chính và màu phụ
- Lỗi, dùng cho văn bản và hộp thoại lỗi
- Thông tin khái quát
- Surface, SurfaceVariant, Surface Inverse
Các vai trò như sau đối với màu chính, màu phụ, màu thứ ba và màu lỗi:
<base color> | Màu cơ bản |
trên<màu cơ bản> | màu của biểu tượng và văn bản xuất hiện trên màu cơ bản |
<màu cơ bản>Container | xuất phát từ màu cơ bản, dùng cho các nút, hộp thoại, v.v. |
on<base color>Container | màu của biểu tượng và văn bản trên vùng chứa |
Ví dụ: Nút hành động nổi có kiểu mặc định trong Material 3 sử dụng Primary làm màu cơ bản, vì vậy, nút này sử dụng primaryContainer cho màu nền và onPrimaryContainer cho nội dung.
Khi tuỳ chỉnh giao diện theo cách thủ công, bạn phải xác minh rằng thuộc tính on<base color> cho mọi màu cơ bản mà bạn thay đổi vẫn dễ đọc.
Phương pháp hay nhất là điều chỉnh tất cả các vai trò trong một nhóm màu cùng một lúc để đảm bảo không có hiện tượng giả tạo từ cơ sở cho đến ứng dụng của bạn.
Màu nền và màu cơ bản của vùng hiển thị thường có 2 vai trò, cho chính màu cơ bản và on<base color> cho biểu tượng hoặc văn bản xuất hiện trên đó.
5. Tạo giao diện Material 3 bằng Material Theme Builder
Công cụ tạo giao diện Material giúp bạn dễ dàng tạo bảng phối màu tuỳ chỉnh, sử dụng tính năng xuất mã tích hợp để di chuyển sang hệ thống màu M3 và tận dụng màu linh động. Tìm hiểu thêm material.io/material-theme-builder
Giao diện ứng dụng Tip Time có một số kiểu cho các thành phần, tuy nhiên, hầu hết các kiểu đều là kiểu mặc định trong giao diện Material 3. Hai màu chính duy nhất mà chúng ta cần quan tâm là màu chính và màu phụ.
Những màu này tương ứng với màu chính là màu xanh lục (#1B5E20) và màu phụ là màu xanh dương (#0288D1).
Bạn có thể nhập những màu đó vào Material Theme Builder và xuất một giao diện đầy đủ (giả sử có một đường liên kết đến phần tổng quan đầy đủ ở nơi khác).
Xin lưu ý rằng các màu bạn nhập có thể thay đổi tông màu để phù hợp với thuật toán tạo màu và đảm bảo các màu bổ sung và dễ đọc.
Dưới đây là một nhóm nhỏ các giá trị được tạo khi bạn nhập màu sắc tuỳ chỉnh.

6. Làm việc với các tệp xuất của Material Theme Builder
Tệp lưu trữ xuất chứa các thư mục values và values-night/ cùng với tệp themes.xml riêng, tương ứng với giao diện sáng và giao diện tối. Tất cả màu sắc đều được xác định trong values/colors.xml.

Bạn có thể sao chép các tệp như hiện trạng nhưng bạn sẽ phải thay đổi tên giao diện AndroidManifest.xml hoặc trong các tệp giao diện cho phù hợp với nhau. Tên mặc định từ công cụ là AppTheme.
Khởi động lại ứng dụng và ứng dụng sẽ trông gần như giống hệt. Một thay đổi đáng chú ý là Switch và RadioButtons. Giờ đây, các trạng thái đã chọn của những thành phần này sẽ được tạo giao diện bằng các tông màu từ màu chính so với màu phụ. Trong các ứng dụng lớn hơn, bạn có thể phải xem lại một số thiết kế.

<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. Thêm màu động
Khi sử dụng một giao diện Material 3 phù hợp, chúng ta có thể tạo giao diện người dùng động bằng một vài điểm bổ sung nhỏ.
Dynamic Colors API cho phép bạn áp dụng màu động cho tất cả các Hoạt động
trong một ứng dụng, các hoạt động riêng lẻ hoặc cho các Khung hiển thị hoặc Mảnh riêng lẻ. Cho
ứng dụng này, chúng ta sẽ áp dụng màu động trên toàn cầu.
Tạo tệp lớp Ứng dụng
class TipTimeApplication: Application() {
override fun onCreate() {
// Apply dynamic color
DynamicColors.applyToActivitiesIfAvailable(this)
}
}
Chúng ta cần tham chiếu tệp mới tạo này trong tệp kê khai Android:
AndroidManifest.xml
< application android name=".TipTimeApplication
<!--- Other existing attributes –>
</application >
Trên các hệ thống Android 12 trở lên, hình nền của người dùng (đối với bảng phối màu mặc định) sẽ được kiểm tra để tạo ra một số bảng tông màu. Các giá trị trong bảng màu này được dùng để tạo ThemeOverlay.
Lớp DynamicColors đăng ký một ActivityLifecycleCallbacks chặn trên ActivityPreCreated để áp dụng lớp phủ giao diện động do hệ thống tạo hoặc lớp phủ do bạn cung cấp.

8. Áp dụng lớp phủ giao diện tuỳ chỉnh
Công cụ của chúng tôi có thể xuất lớp phủ giao diện, nhưng bạn cũng có thể tạo lớp phủ theo cách thủ công nếu đang ghi đè một số ít thuộc tính.
Lớp phủ giao diện được dùng cùng với một giao diện khác và chỉ cung cấp những giá trị sẽ thay đổi trên giao diện cơ sở.
Giả sử vì một lý do nào đó (có thể là để xây dựng thương hiệu), chúng ta cần các tông màu chính là sắc thái của màu đỏ. Chúng tôi có thể thực hiện việc đó với các tệp và thuộc tính sau.
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>
Đối với mã trên, Android 12 sẽ áp dụng một giao diện sáng linh động và phủ các thay đổi của bạn lên trên giao diện đó. Ngoài ra, bạn có thể sử dụng bất kỳ ThemeOverlay hợp lệ nào làm thành phần mẹ, bao gồm cả một trong những thành phần sau:
ThemeOverlay.Material3.Light
ThemeOverlay.Material3.Dark
ThemeOverlay.Material3.DayNight ThemeOverlay.Material3.DynamicColors.Dark
ThemeOverlay.Material3.DynamicColors.DayNight
Để sử dụng Lớp phủ giao diện này thay vì giao diện mặc định của Material, hãy thay đổi lệnh gọi thành DynamicColors.applyToActivitiesIfAvailable thành:
DynamicColors.applyToActivitiesIfAvailable(this, R.style.AppTheme_Overlay)

9. Thêm màu động vào các thuộc tính tuỳ chỉnh
Cho đến nay, chúng ta đã ghi đè các thuộc tính đã có trong một giao diện Material 3. Chúng ta có một trường hợp khác có thể xảy ra trong màu động, đó là chúng ta có thể có một hoặc nhiều thuộc tính tuỳ chỉnh cần được phân bổ.
Khi chọn sử dụng màu động, ứng dụng sẽ có quyền truy cập vào 5 bảng sắc độ – 3 bảng màu nhấn và 2 bảng màu trung tính với các vai trò gần đúng như sau:
system_accent1 | Các sắc độ của màu chính |
system_accent2 | Tông màu phụ |
system_accent3 | Sắc độ màu cấp ba |
system_neutral1 | Nền và bề mặt trung tính |
system_neutral2 | Bề mặt và đường viền trung tính |
Mỗi bảng màu có một số bước định tông màu, từ trắng
đến màu đen: 0, 10, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000.
Khi thiết kế giao diện người dùng cho màu động, bạn nên ít nghĩ về màu sắc cụ thể và nghĩ nhiều hơn về mối quan hệ giữa tông màu và độ sáng của thành phần đó với các thành phần khác trong hệ thống thiết kế.
Giả sử bạn muốn biểu tượng được tạo giao diện bằng bảng màu nhấn phụ và bạn đã thêm một thuộc tính để tạo sắc thái cho biểu tượng bằng mục sau trong attrs.xml.
attrs.xml
<resources>
<attr name="iconColor" format="color" />
</resources>
Lớp phủ giao diện của bạn có thể có dạng như sau:
<style name="AppTheme.Overlay" parent="ThemeOverlay.Material3.DynamicColors.DayNight">
<item name="iconColor">@android:color/system_accent2_600</item>
</style>
Khi bạn cài đặt lại ứng dụng và thay đổi hình nền, ứng dụng sẽ chọn bảng màu phụ đó.


Các bảng màu này dành riêng cho Android 12 (API 31), vì vậy, bạn sẽ cần đặt các tệp có liên quan vào các thư mục có hậu tố -v31, trừ phi ứng dụng của bạn có SDK tối thiểu được đặt thành 31 trở lên.
10. Tóm tắt
Trong lớp học lập trình này, bạn đã có thể:
- Thêm các phần phụ thuộc để nâng cấp giao diện của bạn lên Material 3.
- Tìm hiểu các nhóm màu và vai trò mới.
- Tìm hiểu cách di chuyển từ giao diện tĩnh sang màu động.
- Tìm hiểu cách sử dụng lớp phủ giao diện và sử dụng màu động cho các thuộc tính giao diện tuỳ chỉnh.