Kiểu và giao diện trên Android giúp bạn tách biệt các chi tiết thiết kế ứng dụng khỏi giao diện người dùng cấu trúc và hành vi, tương tự như biểu định kiểu trong thiết kế web.
Kiểu (style) là tập hợp các thuộc tính chỉ định giao diện của một thuộc tính
View
. Kiểu có thể chỉ định các thuộc tính
như màu phông chữ, cỡ chữ, màu nền, v.v.
Giao diện là một tập hợp các thuộc tính được áp dụng cho toàn bộ ứng dụng, hoạt động hoặc chế độ xem chứ không chỉ một chế độ xem riêng lẻ. Khi bạn áp dụng một giao diện, mọi chế độ xem trong ứng dụng hoặc hoạt động sẽ áp dụng từng thuộc tính của giao diện mà nó hỗ trợ. Giao diện cũng có thể áp dụng kiểu cho các phần tử không phải chế độ xem, chẳng hạn như thanh trạng thái và nền cửa sổ.
Kiểu và giao diện được khai báo trong một
tệp tài nguyên kiểu trong
res/values/
, thường có tên là styles.xml
.
![](https://developer.android.com/static/training/material/images/material-themes_2x.png?authuser=19&hl=vi)
Hình 1. 2 giao diện được áp dụng cho cùng một hoạt động:
Theme.AppCompat
(trái) và Theme.AppCompat.Light
(phải).
Giao diện và kiểu
Giao diện và kiểu có nhiều điểm tương đồng, nhưng chúng được sử dụng cho các mục đích khác nhau. Giao diện và kiểu có cùng cấu trúc cơ bản: một cặp khoá-giá trị ánh xạ thuộc tính với tài nguyên của chúng tôi.
Kiểu chỉ định thuộc tính cho một loại thành phần hiển thị cụ thể. Ví dụ: một kiểu có thể chỉ định các thuộc tính của một nút. Mỗi thuộc tính bạn chỉ định trong một kiểu là thuộc tính bạn có thể đặt vào tệp bố cục. Việc trích xuất tất cả các thuộc tính cho một kiểu sẽ giúp bạn dễ dàng sử dụng và duy trì các thuộc tính đó trên nhiều tiện ích.
Giao diện xác định một tập hợp các tài nguyên được đặt tên có thể tham chiếu theo kiểu, bố cục,
tiện ích, v.v. Giao diện chỉ định tên ngữ nghĩa (chẳng hạn như colorPrimary
) cho Android
của chúng tôi.
Các kiểu và giao diện sẽ phối hợp với nhau. Ví dụ: bạn có thể dùng một kiểu giúp xác định
một phần của nút là colorPrimary
và một phần khác là
colorSecondary
Định nghĩa thực tế về các màu đó được cung cấp trong giao diện. Thời gian
thiết bị chuyển sang chế độ ban đêm, ứng dụng của bạn có thể chuyển từ "ánh sáng" giao diện thành "tối" chủ đề,
thay đổi giá trị cho tất cả tên tài nguyên đó. Bạn không cần thay đổi kiểu, vì
các kiểu đang sử dụng tên ngữ nghĩa chứ không phải định nghĩa màu cụ thể.
Để biết thêm thông tin về cách giao diện và kiểu phối hợp hoạt động, hãy xem bài đăng trên blog Định kiểu cho Android: giao diện và kiểu.
Tạo và áp dụng kiểu
Để tạo một kiểu mới, hãy mở tệp res/values/styles.xml
của dự án. Cho
mỗi kiểu bạn muốn tạo, hãy làm theo các bước sau:
- Thêm một thành phần
<style>
có tên giúp nhận dạng chính xác kiểu. - Thêm một thành phần
<item>
cho mỗi thuộc tính kiểu mà bạn muốn xác định. Chiến lược phát hành đĩa đơnname
trong mỗi mục chỉ định một thuộc tính mà bạn sẽ dùng làm thuộc tính XML trong của bạn. Giá trị trong phần tử<item>
là giá trị cho thuộc tính đó.
Ví dụ: giả sử bạn xác định kiểu sau:
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="GreenText" parent="TextAppearance.AppCompat"> <item name="android:textColor">#00FF00</item> </style> </resources>
Bạn có thể áp dụng kiểu cho thành phần hiển thị như sau:
<TextView style="@style/GreenText" ... />
Mỗi thuộc tính được chỉ định trong kiểu sẽ được áp dụng cho thành phần hiển thị đó nếu thành phần hiển thị đó chấp nhận. Chế độ xem bỏ qua mọi thuộc tính mà nó không chấp nhận.
Tuy nhiên, thay vì áp dụng một kiểu cho từng chế độ xem, bạn thường áp dụng kiểu dưới dạng giao diện cho toàn bộ ứng dụng, hoạt động hoặc bộ sưu tập như được mô tả trong một phần khác của hướng dẫn này.
Mở rộng và tuỳ chỉnh kiểu
Khi tạo kiểu của riêng bạn, hãy luôn mở rộng kiểu hiện có trong khung hoặc trang Hỗ trợ
Thư viện để bạn duy trì khả năng tương thích với các kiểu giao diện người dùng của nền tảng. Để mở rộng một kiểu, hãy chỉ định phương thức
kiểu mà bạn muốn mở rộng bằng thuộc tính parent
. Sau đó, bạn có thể ghi đè
và thêm các thuộc tính kiểu mới.
Ví dụ: bạn có thể kế thừa giao diện văn bản mặc định của nền tảng Android và sửa đổi giao diện đó như sau:
<style name="GreenText" parent="@android:style/TextAppearance"> <item name="android:textColor">#00FF00</item> </style>
Tuy nhiên, hãy luôn kế thừa các kiểu ứng dụng cốt lõi từ Thư viện hỗ trợ Android. Kiểu trong
Thư viện hỗ trợ cung cấp khả năng tương thích bằng cách tối ưu hoá từng kiểu cho các thuộc tính giao diện người dùng có sẵn trong
từng phiên bản. Kiểu Thư viện hỗ trợ thường có tên giống với kiểu trên nền tảng,
nhưng có bao gồm AppCompat
.
Để kế thừa kiểu trong thư viện hoặc dự án của riêng bạn, hãy khai báo tên kiểu gốc
không có phần @android:style/
như trong ví dụ trước. Ví dụ:
ví dụ sau kế thừa các kiểu giao diện văn bản từ Thư viện hỗ trợ:
<style name="GreenText" parent="TextAppearance.AppCompat"> <item name="android:textColor">#00FF00</item> </style>
Bạn cũng có thể kế thừa các kiểu (ngoại trừ các kiểu trên nền tảng) bằng cách mở rộng một kiểu
tên bằng ký hiệu dấu chấm, thay vì sử dụng thuộc tính parent
. Tức là thêm tiền tố
tên kiểu của bạn cùng với tên kiểu bạn muốn kế thừa, được phân tách bằng dấu chấm. Bạn
thường chỉ thực hiện việc này khi mở rộng kiểu của riêng bạn chứ không phải kiểu từ các thư viện khác. Ví dụ:
kiểu sau kế thừa tất cả các kiểu từ GreenText
trong ví dụ trước
sau đó tăng kích thước văn bản:
<style name="GreenText.Large"> <item name="android:textSize">22dp</item> </style>
Bạn có thể tiếp tục kế thừa các kiểu như thế này bao nhiêu lần tuỳ thích bằng cách xâu chuỗi thêm tên.
Để biết những thuộc tính bạn có thể khai báo bằng thẻ <item>
, hãy tham khảo tệp "XML
thuộc tính" trong nhiều tệp tham chiếu lớp. Hỗ trợ tất cả lượt xem
Các thuộc tính XML từ cơ sở
View
lớp và nhiều thành phần hiển thị thêm các thuộc tính đặc biệt riêng. Ví dụ:
TextView
thuộc tính XML
bao gồm
android:inputType
mà bạn có thể áp dụng cho khung hiển thị văn bản nhận dữ liệu đầu vào, chẳng hạn như
Tiện ích EditText
.
Áp dụng kiểu dưới dạng giao diện
Bạn có thể tạo một giao diện giống như cách bạn tạo kiểu. Sự khác biệt là cách bạn áp dụng:
thay vì áp dụng kiểu bằng thuộc tính style
trên khung hiển thị, bạn áp dụng giao diện bằng
thuộc tính android:theme
trên thẻ <application>
hoặc
Thẻ <activity>
trong tệp AndroidManifest.xml
.
Ví dụ: dưới đây là cách áp dụng giao diện Material Design "tối" của Thư viện hỗ trợ Android giao diện thành toàn bộ ứng dụng:
<manifest ... > <application android:theme="@style/Theme.AppCompat" ... > </application> </manifest>
Và sau đây là cách áp dụng giao diện "sáng" chỉ cho một hoạt động:
<manifest ... > <application ... > <activity android:theme="@style/Theme.AppCompat.Light" ... > </activity> </application> </manifest>
Mỗi khung hiển thị trong ứng dụng hoặc hoạt động đều áp dụng các kiểu mà khung hiển thị hỗ trợ từ các kiểu được xác định trong chủ đề cụ thể. Nếu một thành phần hiển thị chỉ hỗ trợ một số thuộc tính được khai báo trong kiểu thì thành phần hiển thị đó sẽ được áp dụng chỉ các thuộc tính đó và bỏ qua những thuộc tính mà nó không hỗ trợ.
Kể từ Android 5.0 (API cấp 21) và Thư viện hỗ trợ Android phiên bản 22.1, bạn cũng có thể chỉ định
thuộc tính android:theme
cho một khung hiển thị trong tệp bố cục. Thao tác này sẽ sửa đổi giao diện cho
khung hiển thị đó và bất kỳ khung hiển thị con nào, rất hữu ích khi thay đổi bảng màu giao diện trong một khung hiển thị cụ thể
của giao diện.
Các ví dụ trước minh hoạ cách áp dụng một giao diện, chẳng hạn như Theme.AppCompat
do Thư viện hỗ trợ Android cung cấp. Tuy nhiên, bạn thường muốn tuỳ chỉnh giao diện cho phù hợp
thương hiệu của ứng dụng của bạn. Cách tốt nhất để làm như vậy là mở rộng các kiểu này từ Thư viện hỗ trợ và
ghi đè một số thuộc tính, như được mô tả trong phần sau.
Hệ thống phân cấp kiểu
Android cung cấp nhiều cách để đặt thuộc tính trên ứng dụng Android. Ví dụ: bạn có thể trực tiếp đặt thuộc tính trong một bố cục, áp dụng kiểu cho thành phần hiển thị, áp dụng giao diện cho bố cục và thậm chí đặt thuộc tính theo phương thức lập trình.
Khi chọn cách định kiểu cho ứng dụng, hãy lưu ý đến hệ thống phân cấp kiểu của Android. Nói chung, hãy sử dụng giao diện và kiểu nhiều nhất có thể để đảm bảo tính nhất quán. Nếu bạn chỉ định cùng các thuộc tính trong nhiều vị trí, danh sách sau đây sẽ xác định thuộc tính nào cuối cùng cũng được áp dụng. Danh sách là được sắp xếp theo thứ tự ưu tiên từ cao nhất đến thấp nhất.
- Áp dụng kiểu ở cấp ký tự hoặc đoạn văn bản bằng cách sử dụng span văn bản thành
TextView
khác. - Áp dụng các thuộc tính theo phương thức lập trình.
- Áp dụng trực tiếp các thuộc tính riêng lẻ cho một khung hiển thị.
- Áp dụng kiểu cho thành phần hiển thị.
- Kiểu mặc định.
- Áp dụng giao diện cho một tập hợp thành phần hiển thị, một hoạt động hoặc toàn bộ ứng dụng.
- Áp dụng một số kiểu dành riêng cho thành phần hiển thị, chẳng hạn như đặt
TextAppearance
trênTextView
.
![](https://developer.android.com/static/guide/topics/ui/images/text-multiple-styles.png?authuser=19&hl=vi)
Hình 2. Kiểu trên span
ghi đè kiểu trên textAppearance
.
TextAppearance
Một hạn chế về kiểu là bạn chỉ có thể áp dụng một kiểu cho mỗi View
. Trong một
TextView
, tuy nhiên, bạn cũng có thể chỉ định
Thuộc tính TextAppearance
hoạt động tương tự như kiểu, như trong ví dụ sau:
<TextView ... android:textAppearance="@android:style/TextAppearance.Material.Headline" android:text="This text is styled via textAppearance!" />
TextAppearance
cho phép bạn xác định kiểu cụ thể cho văn bản trong khi vẫn để nguyên kiểu của
Còn View
để sử dụng cho các mục đích khác. Tuy nhiên, lưu ý rằng nếu bạn xác định bất kỳ thuộc tính văn bản nào
trực tiếp trên View
hoặc trong một kiểu, các giá trị đó sẽ ghi đè phương thức
TextAppearance
giá trị.
TextAppearance
hỗ trợ một số thuộc tính định kiểu mà TextView
Google. Để xem danh sách thuộc tính đầy đủ, hãy xem
TextAppearance
.
Có một số thuộc tính TextView
phổ biến không được bao gồm, đó là lineHeight[Multiplier|Extra]
, lines
, breakStrategy
và hyphenationFrequency
.
TextAppearance
hoạt động ở cấp ký tự chứ không phải cấp đoạn, vì vậy
những thuộc tính ảnh hưởng đến toàn bộ bố cục đều không được hỗ trợ.
Tuỳ chỉnh giao diện mặc định
Khi bạn tạo một dự án bằng Android Studio, Android Studio sẽ áp dụng giao diện Material Design cho ứng dụng của bạn bằng cách
mặc định, như xác định trong tệp styles.xml
của dự án. Kiểu AppTheme
này
mở rộng một giao diện từ Thư viện hỗ trợ và bao gồm cả cơ chế ghi đè cho các thuộc tính màu sắc được dùng
theo các thành phần chính trên giao diện người dùng, chẳng hạn như thanh ứng dụng và
nút hành động nổi, nếu có. Vì vậy, bạn
có thể nhanh chóng tuỳ chỉnh thiết kế màu của ứng dụng bằng cách cập nhật màu được cung cấp.
Ví dụ: tệp styles.xml
của bạn có dạng như sau:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style>
Giá trị kiểu thực sự tham chiếu đến
tài nguyên màu, được xác định trong
tệp res/values/colors.xml
của dự án. Đó là tệp mà bạn chỉnh sửa để thay đổi màu.
Xem
Tổng quan về màu sắc trong Material Design
giúp cải thiện trải nghiệm người dùng bằng màu động và màu sắc tuỳ chỉnh bổ sung.
Sau khi bạn chọn xong màu, hãy cập nhật giá trị trong res/values/colors.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <!-- Color for the app bar and other primary UI elements. --> <color name="colorPrimary">#3F51B5</color> <!-- A darker variant of the primary color, used for the status bar (on Android 5.0+) and contextual app bars. --> <color name="colorPrimaryDark">#303F9F</color> <!-- a secondary color for controls like checkboxes and text fields. --> <color name="colorAccent">#FF4081</color> </resources>
Sau đó, bạn có thể ghi đè bất kỳ kiểu nào khác bạn muốn. Ví dụ: bạn có thể thay đổi hoạt động màu nền như sau:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> ... <item name="android:windowBackground">@color/activityBackground</item> </style>
Để biết danh sách các thuộc tính mà bạn có thể sử dụng trong giao diện, hãy xem bảng thuộc tính tại
R.styleable.Theme
. Khi thêm
cho các thành phần hiển thị trong bố cục, bạn cũng có thể tìm thấy các thuộc tính bằng cách xem "thuộc tính XML"
trong bảng tham chiếu lớp chế độ xem. Ví dụ: tất cả các chế độ xem đều hỗ trợ
Các thuộc tính XML trong View
cơ sở
lớp.
Hầu hết thuộc tính được áp dụng cho một số loại thành phần hiển thị cụ thể, còn một số khác áp dụng cho tất cả thành phần hiển thị. Tuy nhiên,
một số thuộc tính giao diện được liệt kê tại
R.styleable.Theme
áp dụng cho
cửa sổ hoạt động chứ không phải chế độ xem trong bố cục. Ví dụ: windowBackground
sẽ thay đổi
nền cửa sổ và windowEnterTransition
xác định một ảnh động chuyển đổi để sử dụng khi
hoạt động bắt đầu. Để biết thêm chi tiết, hãy xem phần Bắt đầu
một hoạt động bằng ảnh động.
Thư viện hỗ trợ Android cũng cung cấp các thuộc tính khác mà bạn có thể dùng để tuỳ chỉnh giao diện của mình
được mở rộng từ Theme.AppCompat
, chẳng hạn như thuộc tính colorPrimary
hiển thị trong
ví dụ trước. Những quảng cáo này được xem nhiều nhất trong
tệp attrs.xml
của thư viện.
Thư viện hỗ trợ cũng có nhiều giao diện khác mà bạn có thể muốn mở rộng
thay cho những thông báo được trình bày trong ví dụ trước. Nơi tốt nhất để xem các chủ đề có sẵn là
thời gian
tệp themes.xml
của thư viện.
Thêm kiểu cho phiên bản cụ thể
Nếu một phiên bản Android mới thêm các thuộc tính giao diện mà bạn muốn sử dụng, thì bạn có thể thêm các thuộc tính đó vào giao diện của mình
mà vẫn tương thích với các phiên bản cũ. Bạn chỉ cần có một tệp styles.xml
khác
được lưu trong thư mục values
bao gồm
phiên bản tài nguyên
bộ hạn định:
res/values/styles.xml # themes for all versions res/values-v21/styles.xml # themes for API level 21+ only
Vì các kiểu trong tệp values/styles.xml
có sẵn cho mọi phiên bản,
giao diện của bạn trong values-v21/styles.xml
có thể kế thừa các giao diện đó. Điều này có nghĩa là bạn có thể tránh
sao chép kiểu gốc bằng cách bắt đầu bằng "cơ sở" chủ đề rồi mở rộng trong giao diện dành riêng cho từng phiên bản của bạn
kiểu.
Ví dụ: để khai báo hiệu ứng chuyển đổi cửa sổ cho Android 5.0 (API cấp 21) trở lên, bạn cần
để sử dụng các thuộc tính mới. Như vậy, giao diện cơ sở của bạn trong res/values/styles.xml
có thể có dạng như sau
sau:
<resources> <!-- Base set of styles that apply to all versions. --> <style name="BaseAppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="colorPrimary">@color/primaryColor</item> <item name="colorPrimaryDark">@color/primaryTextColor</item> <item name="colorAccent">@color/secondaryColor</item> </style> <!-- Declare the theme name that's actually applied in the manifest file. --> <style name="AppTheme" parent="BaseAppTheme" /> </resources>
Sau đó, hãy thêm các kiểu dành riêng cho phiên bản trong res/values-v21/styles.xml
như sau:
<resources> <!-- extend the base theme to add styles available only with API level 21+ --> <style name="AppTheme" parent="BaseAppTheme"> <item name="android:windowActivityTransitions">true</item> <item name="android:windowEnterTransition">@android:transition/slide_right</item> <item name="android:windowExitTransition">@android:transition/slide_left</item> </style> </resources>
Giờ đây, bạn có thể áp dụng AppTheme
trong tệp kê khai và hệ thống sẽ chọn các kiểu
có sẵn cho từng phiên bản hệ thống.
Để biết thêm thông tin về cách sử dụng tài nguyên thay thế cho các thiết bị khác nhau, hãy xem Cung cấp tài nguyên thay thế.
Tuỳ chỉnh kiểu tiện ích
Mỗi tiện ích trong khung và Thư viện hỗ trợ đều có một kiểu mặc định. Ví dụ: khi bạn
tạo kiểu cho ứng dụng của mình bằng giao diện trong Thư viện hỗ trợ, chẳng hạn như
Button
được tạo kiểu bằng phương thức
Kiểu Widget.AppCompat.Button
. Nếu bạn muốn áp dụng kiểu tiện ích khác cho một
, bạn có thể thực hiện việc này bằng thuộc tính style
trong tệp bố cục. Ví dụ:
sau đây áp dụng kiểu nút không đường viền của thư viện:
<Button style="@style/Widget.AppCompat.Button.Borderless" ... />
Nếu muốn áp dụng kiểu này cho tất cả các nút, bạn có thể khai báo kiểu này trong giao diện của mình
buttonStyle
như sau:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="buttonStyle">@style/Widget.AppCompat.Button.Borderless</item> ... </style>
Bạn cũng có thể mở rộng kiểu tiện ích, giống như mở rộng bất kỳ kiểu nào khác, rồi áp dụng kiểu tiện ích tuỳ chỉnh trong bố cục hoặc giao diện.
Tài nguyên khác
Để tìm hiểu thêm về giao diện và kiểu, hãy xem thêm các tài nguyên sau:
Bài đăng trên blog
- Định kiểu cho Android: giao diện và kiểu
- Định kiểu cho Android: các thuộc tính giao diện phổ biến
- Định kiểu cho Android: ưu tiên các thuộc tính giao diện