Tổng quan về tài nguyên ứng dụng

Tài nguyên là các tệp bổ sung và nội dung tĩnh mà đoạn mã của bạn sử dụng, chẳng hạn như bitmap, định nghĩa bố cục, chuỗi giao diện người dùng, hướng dẫn ảnh động, v.v.

Hãy luôn tách riêng các tài nguyên ứng dụng (chẳng hạn như hình ảnh và chuỗi) khỏi đoạn mã để có thể duy trì chúng một cách độc lập. Ngoài ra, hãy cung cấp tài nguyên thay thế cho các cấu hình thiết bị cụ thể bằng cách nhóm những tài nguyên đó trong các thư mục tài nguyên có tên riêng. Trong thời gian chạy, Android sử dụng tài nguyên phù hợp dựa trên cấu hình hiện tại. Ví dụ: bạn nên cung cấp bố cục giao diện người dùng khác nhau dựa trên kích thước màn hình hoặc các chuỗi khác nhau, tuỳ thuộc vào chế độ cài đặt ngôn ngữ.

Sau khi tách tài nguyên ứng dụng, bạn có thể truy cập vào các tài nguyên này bằng cách sử dụng mã nhận dạng tài nguyên được tạo trong lớp R của dự án. Tài liệu này cho bạn biết cách nhóm các tài nguyên trong dự án Android. Tài liệu này cũng chỉ cho bạn cách cung cấp tài nguyên thay thế cho cấu hình thiết bị cụ thể, sau đó truy cập vào những tài nguyên đó từ đoạn mã ứng dụng hoặc các tệp XML khác.

Nhóm các loại tài nguyên

Đặt mỗi loại tài nguyên vào một thư mục con cụ thể thuộc thư mục res/ của dự án. Ví dụ: sau đây là hệ phân cấp tệp của một dự án đơn giản:

MyProject/
    src/
        MyActivity.java
    res/
        drawable/
            graphic.png
        layout/
            main.xml
            info.xml
        mipmap/
            icon.png
        values/
            strings.xml

Thư mục res/ chứa mọi tài nguyên trong các thư mục con: 1 tài nguyên hình ảnh, 2 tài nguyên bố cục, 1 thư mục mipmap/ cho các biểu tượng trình chạy và 1 tệp tài nguyên chuỗi. Tên thư mục tài nguyên rất quan trọng và được mô tả trong bảng 1.

Lưu ý: Để biết thêm thông tin về cách sử dụng thư mục mipmap, hãy xem phần Đặt biểu tượng ứng dụng trong thư mục mipmap.

Bảng 1. Các thư mục tài nguyên được hỗ trợ bên trong thư mục res/ của dự án.

Thư mục Loại tài nguyên
animator/ Tệp XML xác định Ảnh động thuộc tính.
anim/ Tệp XML xác định Ảnh động dạng tween. Bạn cũng có thể lưu ảnh động thuộc tính trong thư mục này. Tuy nhiên, thư mục animator/ sẽ được ưu tiên cho ảnh động thuộc tính để phân biệt giữa 2 loại.
color/ Các tệp XML xác định danh sách trạng thái của màu. Để biết thêm thông tin, hãy xem bài viết Tài nguyên danh sách trạng thái màu.
drawable/

Tệp bitmap (PNG, .9.png, JPG hoặc GIF) hoặc tệp XML được biên dịch thành các loại tài nguyên phụ có thể vẽ sau:

  • Tệp bitmap
  • 9-patch (bitmap có thể thay đổi kích thước)
  • Danh sách trạng thái
  • Hình dạng
  • Ảnh động có thể vẽ
  • Đối tượng có thể vẽ khác

Để biết thêm thông tin, hãy xem bài viết Tài nguyên có thể vẽ.

mipmap/ Các tệp có thể vẽ cho những mật độ biểu tượng trình chạy khác nhau. Để biết thêm thông tin về cách quản lý biểu tượng trình chạy bằng các thư mục mipmap/, vui lòng xem phần Đặt biểu tượng ứng dụng trong thư mục mipmap.
layout/ Tệp XML xác định bố cục giao diện người dùng. Để biết thêm thông tin, hãy xem bài viết Tài nguyên bố cục.
menu/ Các tệp XML xác định trình đơn của ứng dụng, chẳng hạn như trình đơn tuỳ chọn, trình đơn theo bối cảnh hoặc trình đơn phụ. Để biết thêm thông tin, hãy xem bài viết Tài nguyên trình đơn.
raw/

Các tệp tuỳ ý để lưu ở dạng thô của chúng. Để mở các tài nguyên này bằng InputStream thô, hãy gọi Resources.openRawResource() bằng mã nhận dạng tài nguyên là R.raw.filename.

Tuy nhiên, nếu bạn cần quyền truy cập vào tên tệp gốc và hệ phân cấp tệp, hãy cân nhắc việc lưu tài nguyên trong thư mục assets/ thay vì res/raw/. Các tệp trong assets/ không được cung cấp mã nhận dạng tài nguyên nên bạn chỉ có thể đọc các tệp này bằng AssetManager.

values/

Tệp XML chứa các giá trị đơn giản, chẳng hạn như chuỗi, số nguyên và màu.

Trong khi các tệp tài nguyên XML ở các thư mục con res/ khác xác định một tài nguyên duy nhất dựa trên tên tệp XML, thì các tệp trong thư mục values/ sẽ mô tả nhiều tài nguyên. Đối với một tệp trong thư mục này, mỗi thành phần con của phần tử <resources> đều xác định một tài nguyên duy nhất. Ví dụ: phần tử <string> tạo tài nguyên R.string và phần tử <color> tạo tài nguyên R.color.

Vì mỗi tài nguyên được xác định bằng phần tử XML riêng, nên bạn có thể tuỳ ý đặt tên cho tệp và đặt nhiều loại tài nguyên trong một tệp. Tuy nhiên, để cho rõ ràng, bạn nên đặt những loại tài nguyên duy nhất trong các tệp khác nhau. Ví dụ: sau đây là một số quy ước về tên tệp cho những tài nguyên mà bạn có thể tạo trong thư mục này:

Để biết thêm thông tin, hãy xem bài viết Tài nguyên chuỗi, Tài nguyên kiểuCác loại tài nguyên khác.

xml/ Tệp XML tuỳ ý có thể được đọc trong thời gian chạy bằng cách gọi Resources.getXML(). Bạn phải lưu các tệp cấu hình XML khác nhau vào đây, chẳng hạn như Cấu hình tìm kiếm.
font/ Các tệp phông chữ có đuôi như TTF, OTF hoặc TTC, hoặc các tệp XML có chứa phần tử <font-family>. Để biết thêm thông tin về phông chữ ở dạng tài nguyên, hãy xem bài viết Thêm phông chữ ở dạng tài nguyên XML.

Thận trọng: Đừng bao giờ lưu tệp tài nguyên ngay trong thư mục res/ vì việc này sẽ gây ra lỗi trình biên dịch.

Để biết thêm thông tin về các loại tài nguyên riêng lẻ, hãy xem bài viết Tổng quan về các loại tài nguyên.

Tài nguyên mà bạn lưu trong các thư mục con được xác định trong bảng 1 là tài nguyên mặc định. Tức là những tài nguyên này xác định thiết kế và nội dung mặc định cho ứng dụng của bạn. Tuy nhiên, mỗi loại thiết bị chạy Android có thể yêu cầu các loại tài nguyên khác nhau.

Ví dụ: bạn có thể cung cấp nhiều tài nguyên bố cục cho các thiết bị có màn hình lớn hơn bình thường để tận dụng không gian màn hình bổ sung. Bạn cũng có thể cung cấp nhiều tài nguyên chuỗi để dịch văn bản trong giao diện người dùng dựa trên chế độ cài đặt ngôn ngữ của thiết bị. Để cung cấp các tài nguyên khác nhau này cho nhiều cấu hình thiết bị, bạn cần cung cấp tài nguyên thay thế cùng với tài nguyên mặc định.

Cung cấp tài nguyên thay thế

Hầu hết ứng dụng đều cung cấp tài nguyên thay thế để hỗ trợ các cấu hình thiết bị cụ thể. Ví dụ: thêm các tài nguyên có thể vẽ thay thế cho nhiều mật độ màn hình và tài nguyên chuỗi thay thế cho nhiều ngôn ngữ. Trong thời gian chạy, Android sẽ phát hiện cấu hình thiết bị hiện tại và tải các tài nguyên thích hợp cho ứng dụng của bạn.

Hình 1. 2 thiết bị sử dụng tài nguyên bố cục khác nhau dựa trên kích thước màn hình.

Để chỉ định các tài nguyên thay thế theo cấu hình cụ thể cho một nhóm tài nguyên, hãy làm như sau:

  1. Tạo một thư mục mới trong res/ có tên trong biểu mẫu <resources_name>-<qualifier>.
    • <resources_name> là tên thư mục của các tài nguyên mặc định tương ứng (được xác định trong bảng 1).
    • <qualifier> là tên chỉ định một cấu hình riêng lẻ để sử dụng những tài nguyên này (được xác định trong bảng 2).

    Bạn có thể thêm nhiều <qualifier>. Phân tách từng mã bằng dấu gạch ngang.

    Chú ý: Khi thêm nhiều bộ hạn định, bạn phải đặt các bộ hạn định đó theo thứ tự được liệt kê trong bảng 2. Nếu bạn sắp xếp các bộ hạn định không chính xác, thì các tài nguyên sẽ bị bỏ qua.

  2. Lưu các tài nguyên thay thế thích hợp trong thư mục mới này. Các tệp tài nguyên phải được đặt tên giống hệt với tệp tài nguyên mặc định.

Ví dụ: dưới đây là một số tài nguyên mặc định và tài nguyên thay thế:

res/
    drawable/
        icon.png
        background.png
    drawable-hdpi/
        icon.png
        background.png

Bộ hạn định hdpi cho biết các tài nguyên trong thư mục đó dành cho các thiết bị có màn hình với độ phân giải cao. Hình ảnh trong các thư mục có thể vẽ này được định kích thước cho mật độ màn hình cụ thể, nhưng tên tệp thì giống hệt nhau. Bằng cách này, mã nhận dạng tài nguyên mà bạn dùng để tham chiếu hình ảnh icon.png hoặc background.png luôn giống nhau. Android chọn phiên bản của từng tài nguyên phù hợp nhất với thiết bị hiện tại bằng cách so sánh thông tin cấu hình thiết bị với bộ hạn định trong tên thư mục tài nguyên.

Thận trọng: Khi xác định tài nguyên thay thế, hãy đảm bảo bạn cũng xác định tài nguyên trong cấu hình mặc định. Nếu không, ứng dụng của bạn có thể gặp phải trường hợp ngoại lệ về thời gian chạy khi thiết bị thay đổi cấu hình. Ví dụ: nếu bạn chỉ thêm một chuỗi vào values-en chứ không phải values, ứng dụng của bạn có thể gặp phải ngoại lệ Resource Not Found khi người dùng thay đổi ngôn ngữ mặc định của hệ thống.

Bảng 2 liệt kê các bộ hạn định cấu hình hợp lệ theo thứ tự ưu tiên. Bạn có thể thêm nhiều bộ hạn định vào một tên thư mục bằng cách dùng dấu gạch ngang phân tách từng bộ hạn định. Nếu sử dụng nhiều bộ hạn định cho một thư mục tài nguyên, bạn phải thêm các bộ hạn định đó vào tên thư mục theo thứ tự liệt kê trong bảng.

Bảng 2. Tên bộ hạn định cấu hình.

Cấu hình Giá trị bộ hạn định Nội dung mô tả
MCC và MNC Ví dụ:
mcc310
mcc310-mnc004
mcc208-mnc00

Mã di động quốc gia (MCC), theo sau là mã mạng di động (MNC) (không bắt buộc) có trên thẻ SIM trong thiết bị. Ví dụ: mcc310 là Hoa Kỳ trên bất kỳ nhà mạng nào, mcc310-mnc004 là Hoa Kỳ trên nhà mạng Verizon và mcc208-mnc00 là Pháp trên nhà mạng Orange.

Nếu thiết bị sử dụng kết nối vô tuyến (tức là điện thoại GSM), thì giá trị MCC và MNC sẽ có trên thẻ SIM.

Bạn cũng có thể sử dụng riêng MCC, ví dụ: để đưa các tài nguyên pháp lý ở từng quốc gia vào ứng dụng của bạn. Nếu bạn chỉ cần chỉ định dựa trên ngôn ngữ, hãy dùng bộ hạn định ngôn ngữ, tập lệnh (không bắt buộc) và khu vực (không bắt buộc). Nếu bạn dùng bộ hạn định MCC và MNC, hãy cẩn thận khi làm vậy và kiểm thử để chắc chắn chúng hoạt động như dự kiến.

Ngoài ra, hãy xem các trường cấu hình mccmnc để biết mã di động quốc gia và mã mạng di động hiện tại tương ứng.

Ngôn ngữ, tập lệnh (không bắt buộc) và khu vực (không bắt buộc) Ví dụ:
en
fr
en-rUS
fr-rFR
fr-rCA
b+en
b+en+US
b+es+419
b+zh+Hant
b+sr+Latn+RS

Ngôn ngữ này được xác định bằng mã ngôn ngữ gồm 2 chữ cái theo tiêu chuẩn ISO 639-1, có thể theo sau là mã vùng gồm 2 chữ cái theo tiêu chuẩn ISO 3166-1-alpha-2 (đứng trước r viết thường).

Các mã này không phân biệt chữ hoa chữ thường. Tiền tố r được dùng để phân biệt phần khu vực. Bạn không thể chỉ định riêng một khu vực.

Android 7.0 (API cấp 24) đã ra mắt tính năng hỗ trợ thẻ ngôn ngữ BCP 47. Bạn có thể dùng các thẻ này để đáp ứng điều kiện về tài nguyên dành riêng cho từng ngôn ngữ và khu vực. Thẻ ngôn ngữ được tạo từ một trình tự gồm một hoặc nhiều thẻ phụ, mỗi thẻ trong số đó sẽ tinh chỉnh hoặc thu hẹp phạm vi ngôn ngữ mà thẻ tổng thể xác định. Để biết thêm thông tin về thẻ ngôn ngữ, hãy xem phần Thẻ để xác định ngôn ngữ.

Để sử dụng thẻ ngôn ngữ BCP 47, hãy nối b+ với một mã ngôn ngữ gồm 2 chữ cái theo tiêu chuẩn ISO 639-1, có thể theo sau là các thẻ phụ bổ sung được phân tách bằng +.

Thẻ ngôn ngữ có thể thay đổi trong suốt thời gian hoạt động của ứng dụng nếu người dùng thay đổi ngôn ngữ trong phần cài đặt hệ thống. Để biết thông tin về mức độ ảnh hưởng của thay đổi này đến ứng dụng của bạn trong thời gian chạy, hãy xem bài viết Xử lý các thay đổi về cấu hình.

Để xem hướng dẫn đầy đủ về cách bản địa hoá ứng dụng cho các ngôn ngữ khác, hãy xem bài viết Bản địa hoá ứng dụng.

Ngoài ra, hãy xem phương thức getLocales(), phương thức này cung cấp danh sách các ngôn ngữ được xác định. Danh sách này bao gồm ngôn ngữ chính.

Hướng bố cục ldrtl
ldltr

Hướng bố cục của ứng dụng. ldrtl có nghĩa là "hướng bố cục từ phải sang trái". ldltr có nghĩa là "hướng bố cục từ trái sang phải" và là giá trị mặc định ngầm ẩn.

Cách này có thể áp dụng cho mọi tài nguyên như bố cục, đối tượng có thể vẽ hoặc giá trị.

Ví dụ: nếu bạn muốn cung cấp một bố cục cụ thể cho ngôn ngữ Ả Rập và một bố cục chung cho ngôn ngữ "từ phải sang trái" khác, như tiếng Ba Tư hoặc tiếng Do Thái, hãy sử dụng các thư mục như sau:

res/
  layout/
    main.xml (bố cục mặc định)
  layout-ar/
    main.xml (bố cục cụ thể cho tiếng Ả Rập)
  layout-ldrtl/
    main.xml (mọi ngôn ngữ "từ phải sang trái", ngoại trừ tiếng Ả Rập, vì bộ hạn định ngôn ngữ "ar" có mức độ ưu tiên cao hơn)

Lưu ý: Để bật các tính năng bố cục từ phải sang trái cho ứng dụng, bạn phải đặt SupportsRtl thành "true" và đặt TargetSdkVersion thành 17 trở lên.

Đã thêm vào API cấp 17.

Chiều rộng nhỏ nhất sw<N>dp

Ví dụ:
sw320dp
sw600dp
sw720dp
, v.v.

Kích thước ngắn nhất của diện tích màn hình có sẵn cho một ứng dụng. Cụ thể, smallestWidth của cửa sổ ứng dụng là kích thước ngắn nhất của chiều cao và chiều rộng có sẵn cho cửa sổ đó. Bạn cũng có thể coi kích thước này là "chiều rộng nhỏ nhất có thể" cho cửa sổ. Bạn có thể dùng bộ hạn định này để giao diện người dùng của ứng dụng có chiều rộng tối thiểu là <N> dp.

Ví dụ: nếu bố cục yêu cầu kích thước nhỏ nhất của diện tích màn hình luôn phải tối thiểu là 600 dp, thì bạn có thể dùng bộ hạn định này để tạo tài nguyên bố cục trong thư mục res/layout-sw600dp/. Hệ thống chỉ sử dụng các tài nguyên này khi kích thước nhỏ nhất của màn hình có sẵn tối thiểu là 600 dp, bất kể 600 dp là chiều cao hay chiều rộng mà người dùng nhìn thấy. Chiều rộng nhỏ nhất có thể thay đổi nếu cửa sổ được đổi kích thước (thay đổi chiều rộng/chiều cao có sẵn) hoặc thay đổi vị trí (có thể thay đổi phần lồng ghép của hệ thống).

Việc sử dụng chiều rộng nhỏ nhất để xác định kích thước màn hình chung sẽ hữu ích vì chiều rộng thường là yếu tố thúc đẩy trong quá trình thiết kế bố cục. Một giao diện người dùng thường cuộn theo chiều dọc, nhưng có những hạn chế khá khó khăn về không gian tối thiểu mà giao diện người dùng cần theo chiều ngang.

Chiều rộng có sẵn cũng là yếu tố quan trọng để xác định xem nên sử dụng bố cục một ngăn cho các điện thoại di động hay bố cục nhiều ngăn cho máy tính bảng. Do đó, bạn có thể sẽ quan tâm nhất đến chiều rộng nhỏ nhất có thể trên mỗi thiết bị.

Chiều rộng nhỏ nhất của thiết bị bao gồm phần trang trí màn hình và giao diện người dùng của hệ thống. Ví dụ: nếu thiết bị có một số phần tử cố định trên giao diện người dùng trên màn hình chiếm không gian dọc theo trục của chiều rộng nhỏ nhất, thì hệ thống sẽ khai báo chiều rộng nhỏ nhất là nhỏ hơn kích thước màn hình thực tế, vì đó là những pixel màn hình không được hỗ trợ cho giao diện người dùng của bạn.

Dưới đây là một số giá trị mà bạn có thể sử dụng cho các kích thước màn hình phổ biến:

  • 320, đối với các thiết bị có cấu hình màn hình như:
    • 240x320 ldpi (điện thoại di động QVGA)
    • 320x480 mdpi (điện thoại di động)
    • 480 x 800 hdpi (điện thoại di động có độ phân giải màn hình cao)
  • 480, đối với các màn hình như 480 x 800 mdpi (máy tính bảng/điện thoại di động)
  • 600, đối với màn hình như 600 x 1024 mdpi (máy tính bảng 7 inch)
  • 720, đối với màn hình như 720 x 1280 mdpi (máy tính bảng 10 inch)

Khi ứng dụng của bạn cung cấp nhiều thư mục tài nguyên có giá trị khác nhau cho bộ hạn định smallestWidth, hệ thống sẽ dùng giá trị gần nhất với smallestWidth của thiết bị (mà không được vượt quá).

Đã thêm vào API cấp 13.

Ngoài ra, hãy xem thuộc tính android:requiresSmallestWidthDp khai báo smallestWidth tối thiểu tương thích với ứng dụng của bạn và trường cấu hình smallestScreenWidthDp chứa giá trị smallestWidth của thiết bị.

Để biết thêm thông tin về cách thiết kế cho nhiều màn hình bằng bộ hạn định này, hãy xem Thiết kế thích ứng bằng khung hiển thị.

Chiều rộng và chiều cao có sẵn w<N>dp
h<N>dp

Ví dụ:
w720dp
w1024dp
h720dp
h1024dp
, v.v.

Chỉ định chiều rộng hoặc chiều cao tối thiểu cho màn hình hiện có (tính bằng đơn vị dp do giá trị <N> xác định) mà tài nguyên sẽ được sử dụng. Các giá trị cấu hình này được so sánh với chiều rộng và chiều cao màn hình hiện tại khi hướng thiết bị thay đổi giữa chế độ dọc và chế độ ngang, thiết bị gập hoặc mở ra hay hệ thống chuyển sang hoặc thoát khỏi chế độ nhiều cửa sổ. Ở chế độ nhiều cửa sổ, các giá trị phản ánh chiều rộng và chiều cao của cửa sổ chứa ứng dụng, chứ không phải chiều rộng và chiều cao của màn hình thiết bị. Tương tự, đối với các hoạt động được nhúng, các giá trị liên quan đến chiều rộng và chiều cao của từng hoạt động riêng lẻ, chứ không phải chiều rộng và chiều cao của màn hình. Để biết thêm thông tin, hãy xem bài viết Nhúng hoạt động.

Chiều rộng và chiều cao có sẵn thường hữu ích cho việc xác định xem có nên sử dụng bố cục nhiều ngăn hay không, vì ngay cả trên thiết bị máy tính bảng, bạn cũng không muốn sử dụng cùng một bố cục nhiều ngăn cho hướng dọc như đối với hướng ngang. Do đó, bạn có thể sử dụng các mã này để chỉ định chiều rộng và/hoặc chiều cao tối thiểu cần thiết cho bố cục, thay vì sử dụng cả bộ hạn định kích thước màn hình lẫn bộ hạn định hướng.

Khi ứng dụng của bạn cung cấp nhiều thư mục tài nguyên có giá trị khác nhau cho các cấu hình này, hệ thống sẽ sử dụng giá trị gần nhất với chiều rộng màn hình hiện tại của thiết bị (mà không được vượt quá). Giá trị gần nhất được xác định bằng cách thêm hiệu số giữa chiều rộng màn hình thực tế và chiều rộng đã chỉ định với hiệu số giữa chiều cao màn hình thực tế và chiều cao đã chỉ định, với chiều rộng và chiều cao chưa chỉ định có giá trị là 0.

Các giá trị loại trừ khu vực bị chiếm bởi Phần lồng ghép cửa sổ. Vì vậy, nếu thiết bị có phần tử cố định trên giao diện người dùng ở các mép màn hình, thì các giá trị của chiều rộng và chiều cao sẽ nhỏ hơn kích thước màn hình thực, ngay cả khi ứng dụng hiển thị cạnh nhau bằng cách sử dụng Window.setDecorFitsSystemWindows hoặc WindowCompat.setDecorFitsSystemWindows.

Một số thành phần trang trí màn hình dọc không cố định (chẳng hạn như thanh trạng thái trên điện thoại có thể bị ẩn khi ở chế độ toàn màn hình) không được tính ở đây. Các thành phần trang trí cửa sổ như thanh tiêu đề hoặc thanh thao tác cũng vậy. Do đó, các ứng dụng phải được chuẩn bị để xử lý một không gian có phần nhỏ hơn so với ứng dụng.

Lưu ý: Hệ thống sẽ chọn tài nguyên phù hợp với cả chiều rộng và chiều cao. Do đó, một tài nguyên chỉ định cả chiều rộng và chiều cao sẽ được ưu tiên hơn một tài nguyên chỉ chỉ định một trong hai kích thước này. Ví dụ: nếu màn hình thực tế là 720 dp x 1280 dp (chiều rộng x chiều cao) và một tài nguyên đủ điều kiện với chiều rộng 720 dp cùng một tài nguyên khác đủ điều kiện với chiều rộng 700 dp – chiều cao 1200 dp, thì tài nguyên thứ hai sẽ được chọn ngay cả tài nguyên thứ nhất hoàn toàn khớp với giá trị chỉ định.

Đã thêm vào API cấp 13.

Ngoài ra, hãy xem các trường cấu hình screenWidthDpscreenHeightDp chứa chiều rộng và chiều cao hiện tại của màn hình.

Để biết thêm thông tin về cách thiết kế cho nhiều màn hình bằng bộ hạn định này, hãy xem Thiết kế thích ứng bằng khung hiển thị.

Kích thước màn hình small
normal
large
xlarge
  • small: màn hình có kích thước tương tự như màn hình QVGA với độ phân giải thấp. Kích thước bố cục tối thiểu cho màn hình nhỏ là khoảng 320 x 426 dp. Ví dụ: màn hình QVGA với độ phân giải thấp và màn hình VGA với độ phân giải cao.
  • normal: màn hình có kích thước tương tự như màn hình HVGA với độ phân giải trung bình. Kích thước bố cục tối thiểu cho màn hình thông thường là khoảng 320 x 470 dp. Ví dụ về những màn hình như vậy gồm có màn hình WQVGA với độ phân giải thấp, màn hình HVGA với độ phân giải trung bình và màn hình WVGA với độ phân giải cao.
  • large: màn hình có kích thước tương tự như màn hình VGA với độ phân giải trung bình. Kích thước bố cục tối thiểu cho một màn hình lớn là khoảng 480 x 640 dp. Ví dụ: màn hình VGA và WVGA với độ phân giải trung bình.
  • xlarge: màn hình lớn hơn đáng kể so với màn hình HVGA với độ phân giải trung bình truyền thống. Kích thước bố cục tối thiểu cho một màn hình cực đại là khoảng 720 x 960 dp. Trong hầu hết trường hợp, thiết bị có màn hình cực lớn sẽ quá lớn nên không thể cho vào túi và rất có thể là các thiết bị kiểu máy tính bảng. Đã thêm vào API cấp 9.

Lưu ý: Việc sử dụng bộ hạn định kích thước không có nghĩa là tài nguyên chỉ dành cho các màn hình có kích thước đó. Nếu bạn không cung cấp tài nguyên thay thế có bộ hạn định phù hợp hơn với cấu hình thiết bị hiện tại, hệ thống có thể sử dụng bất kỳ tài nguyên nào phù hợp nhất.

Thận trọng: Nếu mọi tài nguyên của bạn đều sử dụng bộ hạn định kích thước lớn hơn màn hình hiện tại, thì hệ thống sẽ không dùng những tài nguyên đó và ứng dụng của bạn sẽ gặp sự cố trong thời gian chạy. Ví dụ: sự cố này xảy ra nếu tất cả các tài nguyên bố cục được gắn thẻ với bộ hạn định xlarge, nhưng thiết bị có màn hình ở kích thước bình thường.

Đã thêm vào API cấp 4.

Ngoài ra, hãy xem trường cấu hình screenLayout để biết màn hình là loại nhỏ, bình thường hay lớn.

Để biết thêm thông tin, hãy xem bài viết Tổng quan về khả năng tương thích với màn hình.

Tỷ lệ màn hình long
notlong
  • long: màn hình dài, chẳng hạn như WQVGA, WVGA, FWVGA
  • notlong: không phải màn hình dài, chẳng hạn như QVGA, HVGA và VGA

Đã thêm vào API cấp 4.

Tỷ lệ màn hình hoàn toàn dựa vào tỷ lệ khung hình của màn hình (màn hình long rộng hơn). Tỷ lệ màn hình không liên quan đến hướng màn hình.

Ngoài ra, hãy xem trường cấu hình screenLayout để biết màn hình có dài hay không.

Màn hình tròn round
notround
  • round: màn hình tròn, chẳng hạn như thiết bị đeo hình tròn
  • notround: màn hình hình chữ nhật, chẳng hạn như điện thoại hoặc máy tính bảng

Đã thêm vào API cấp 23.

Ngoài ra, hãy xem phương thức cấu hình isScreenRound() để biết màn hình có tròn không.

Gam màu rộng widecg
nowidecg
  • widecg: các màn hình có gam màu rộng, chẳng hạn như Display P3 hoặc AdobeRGB
  • nowidecg: các màn hình có gam màu hẹp, chẳng hạn như sRGB

Đã thêm vào API cấp 26.

Ngoài ra, hãy xem phương thức cấu hình isScreenWideColorGamut() để biết màn hình có gam màu rộng hay không.

Dải động cao (HDR) highdr
lowdr
  • highdr: các màn hình có dải động cao
  • lowdr: các màn hình có dải động thấp/chuẩn

Đã thêm vào API cấp 26.

Ngoài ra, hãy xem phương thức cấu hình isScreenHdr() để biết màn hình có tính năng HDR hay không.

Hướng màn hình port
land
  • port: thiết bị theo hướng dọc (dọc)
  • land: thiết bị theo hướng ngang (ngang)

Hướng màn hình có thể thay đổi trong suốt thời gian hoạt động của ứng dụng nếu người dùng xoay màn hình. Để biết thông tin về mức độ ảnh hưởng của thay đổi này đến ứng dụng của bạn trong thời gian chạy, hãy xem bài viết Xử lý các thay đổi về cấu hình.

Ngoài ra, hãy xem trường cấu hình orientation để biết hướng của thiết bị hiện tại.

Chế độ giao diện người dùng car
desk
television
appliance
watch
vrheadset
  • car: thiết bị đang hiển thị trong đế trên ô tô
  • desk: thiết bị đang hiển thị trong một đế để bàn
  • television: thiết bị đang hiển thị trên TV, mang đến trải nghiệm "10 feet" mà trong đó giao diện người dùng của thiết bị này nằm trên một màn hình lớn mà người dùng ở xa. Trải nghiệm này chủ yếu được định hướng xung quanh D-pad hoặc chế độ tương tác khác không phải con trỏ
  • appliance: thiết bị đang hoạt động như một thiết bị không có màn hình
  • watch: thiết bị có màn hình và được đeo trên cổ tay
  • vrheadset: thiết bị đang hiển thị trong kính thực tế ảo

Đã thêm vào API cấp 8; TV được thêm vào API 13; đồng hồ được thêm vào API 20.

Để biết thông tin về cách ứng dụng của bạn có thể phản hồi khi thiết bị được cắm vào hoặc bị tháo khỏi đế, hãy đọc bài viết Xác định và theo dõi trạng thái cũng như loại đế sạc.

Các chế độ này có thể thay đổi trong quá trình hoạt động của ứng dụng nếu người dùng đặt thiết bị vào một đế. Bạn có thể bật hoặc tắt một số chế độ này bằng UiModeManager. Để biết thông tin về mức độ ảnh hưởng của thay đổi này đến ứng dụng của bạn trong thời gian chạy, hãy xem bài viết Xử lý các thay đổi về cấu hình.

Chế độ ban đêm night
notnight
  • night: ban đêm
  • notnight: ban ngày

Đã thêm vào API cấp 8.

Điều này có thể thay đổi trong quá trình hoạt động của ứng dụng nếu bạn để chế độ ban đêm ở chế độ tự động (mặc định). Trong trường hợp này, chế độ này thay đổi dựa vào thời gian trong ngày. Bạn có thể bật hoặc tắt chế độ này bằng UiModeManager. Để biết thông tin về mức độ ảnh hưởng của thay đổi này đến ứng dụng của bạn trong thời gian chạy, hãy xem bài viết Xử lý các thay đổi về cấu hình.

Mật độ pixel màn hình (dpi) ldpi
mdpi
hdpi
xhdpi
xxhdpi
xxxhdpi
nodpi
tvdpi
anydpi
nnndpi
  • ldpi: màn hình có độ phân giải thấp; khoảng 120 dpi.
  • mdpi: màn hình có độ phân giải trung bình (trên HVGA truyền thống); khoảng 160 dpi.
  • hdpi: màn hình có độ phân giải cao; khoảng 240 dpi.
  • xhdpi: màn hình có độ phân giải cực cao; khoảng 320 dpi. Đã thêm vào API cấp 8.
  • xxhdpi: màn hình có độ phân giải cực cực cao; khoảng 480 dpi. Đã thêm vào API cấp 16.
  • xxxhdpi: sử dụng mật độ cực cực cực cao (chỉ biểu tượng trình chạy – xem bài viết Hỗ trợ nhiều mật độ pixel); khoảng 640 dpi. Đã thêm vào API cấp 18.
  • nodpi: dùng cho các tài nguyên bitmap mà bạn không muốn điều chỉnh theo tỷ lệ cho phù hợp với độ phân giải màn hình của thiết bị.
  • tvdpi: màn hình ở đâu đó giữa mdpi và hdpi; khoảng 213 dpi. Đây không được coi là nhóm mật độ "chính". Màn hình này chủ yếu dành cho TV 720p mà hầu hết các ứng dụng không cần dùng đến. Đối với màn hình TV 1080p, hãy dùng xhdpi, còn đối với màn hình TV 4K, hãy dùng xxxhdpi. Đã thêm vào API cấp 13.
  • anydpi: khớp với mọi mật độ màn hình và được ưu tiên hơn các bộ hạn định khác. Mật độ này sẽ hữu ích cho vectơ vẽ được. Đã thêm vào API cấp 21.
  • nnndpi: dùng để biểu thị mật độ không chuẩn, trong đó nnn là mật độ màn hình có số nguyên dương. Mật độ này không được sử dụng trong hầu hết các trường hợp. Việc sử dụng nhóm mật độ chuẩn giúp giảm đáng kể chi phí khi phải hỗ trợ nhiều mật độ màn hình của thiết bị trên thị trường.

Có một tỷ lệ xích là 3:4:6:8:12:16 giữa 6 mật độ chính (bỏ qua mật độ tvdpi). Vì vậy, một bitmap 9x9 ở ldpi là 12x12 ở mdpi, 18x18 ở hdpi, 24x24 ở xhdpi, v.v.

Lưu ý: Việc sử dụng bộ hạn định mật độ không có nghĩa là tài nguyên chỉ dành cho màn hình có mật độ đó. Nếu bạn không cung cấp tài nguyên thay thế có bộ hạn định phù hợp hơn với cấu hình thiết bị hiện tại, thì hệ thống có thể sử dụng bất kỳ tài nguyên nào phù hợp nhất.

Để biết thêm thông tin về cách xử lý các mật độ màn hình khác nhau và cách Android có thể điều chỉnh bitmap theo tỷ lệ cho phù hợp với mật độ hiện tại, hãy xem bài viết Tổng quan về khả năng tương thích với màn hình.

Loại màn hình cảm ứng notouch
finger
  • notouch: thiết bị không có màn hình cảm ứng.
  • finger: thiết bị có màn hình cảm ứng dùng để tương tác theo hướng ngón tay của người dùng.

Ngoài ra, hãy xem trường cấu hình touchscreen để biết loại màn hình cảm ứng trên thiết bị.

Khả năng sử dụng bàn phím keysexposed
keyshidden
keyssoft
  • keysexposed: thiết bị có bàn phím. Nếu thiết bị (có thể) đã bật bàn phím phần mềm, thì bạn có thể sử dụng tính năng này ngay cả khi bàn phím phần cứng không hiển thị với người dùng hoặc thiết bị không có bàn phím phần cứng. Nếu bàn phím phần mềm không được cung cấp hoặc bị tắt, thì tính năng này chỉ được sử dụng khi bàn phím phần cứng hiển thị.
  • keyshidden: thiết bị có bàn phím phần cứng nhưng bị ẩn thiết bị không bật bàn phím phần mềm.
  • keyssoft: thiết bị đã bật bàn phím phần mềm, cho dù người dùng có nhìn thấy bàn phím đó hay không.

Nếu bạn cung cấp tài nguyên keysexposed nhưng không cung cấp tài nguyên keyssoft, hệ thống sẽ sử dụng tài nguyên keysexposed bất kể bàn phím có hiển thị hay không, miễn là hệ thống đã bật bàn phím phần mềm.

Điều này có thể thay đổi trong quá trình hoạt động của ứng dụng nếu người dùng mở bàn phím phần cứng. Để biết thông tin về mức độ ảnh hưởng của thay đổi này đến ứng dụng của bạn trong thời gian chạy, hãy xem bài viết Xử lý các thay đổi về cấu hình.

Ngoài ra, hãy xem các trường cấu hình hardKeyboardHiddenkeyboardHidden để biết chế độ hiển thị của bàn phím phần cứng và chế độ hiển thị của bất kỳ loại bàn phím nào (bao gồm cả bàn phím phần mềm) tương ứng.

Phương thức nhập văn bản chính nokeys
qwerty
12key
  • nokeys: thiết bị không có khoá phần cứng để nhập văn bản.
  • qwerty: thiết bị có bàn phím phần cứng dạng QWERTY, cho dù người dùng có nhìn thấy bàn phím đó hay không.
  • 12key: thiết bị có bàn phím phần cứng dạng 12 phím, cho dù người dùng có nhìn thấy bàn phím đó hay không.

Ngoài ra, hãy xem trường cấu hình keyboard để biết phương thức nhập văn bản chính hiện có.

Phiên bản nền tảng (cấp độ API) Ví dụ:
v3
v4
v7
, v.v.

Cấp độ API mà thiết bị hỗ trợ. Ví dụ: v1 cho API cấp 1 (thiết bị chạy Android 1.0 trở lên) và v4 cho API cấp 4 (thiết bị chạy Android 1.6 trở lên). Để biết thêm thông tin về các giá trị này, hãy xem tài liệu về Cấp độ API Android.

Lưu ý: Không phải phiên bản Android nào cũng hỗ trợ mọi bộ hạn định. Việc sử dụng bộ hạn định mới sẽ ngầm thêm bộ hạn định phiên bản nền tảng để các thiết bị cũ có thể bỏ qua bộ hạn định đó. Ví dụ: việc sử dụng bộ hạn định w600dp sẽ tự động bao gồm bộ hạn định v13, vì bộ hạn định loại có sẵn chiều rộng là mới trong API cấp 13. Để tránh mọi sự cố, hãy luôn bao gồm một nhóm tài nguyên mặc định (một nhóm tài nguyên không có bộ hạn định). Để biết thêm thông tin, vui lòng xem phần Cung cấp khả năng tương thích tốt nhất với thiết bị bằng tài nguyên.

Quy tắc về tên bộ hạn định

Dưới đây là một số quy tắc về việc sử dụng tên bộ hạn định cấu hình:

  • Bạn có thể chỉ định nhiều bộ hạn định cho một nhóm tài nguyên, phân tách bằng dấu gạch ngang. Ví dụ: drawable-en-rUS-land áp dụng cho các thiết bị Tiếng Anh-Mỹ theo hướng ngang.
  • Bộ hạn định phải theo thứ tự được liệt kê trong bảng 2.
    • Sai: drawable-hdpi-port/
    • Đúng: drawable-port-hdpi/
  • Không thể lồng các thư mục tài nguyên thay thế. Ví dụ: bạn không thể có res/drawable/drawable-en/.
  • Các giá trị không phân biệt chữ hoa chữ thường. Trình biên dịch tài nguyên chuyển đổi tên thư mục thành chữ thường trước khi xử lý để tránh các sự cố trên hệ thống tệp không phân biệt chữ hoa chữ thường. Mọi cách viết hoa trong tên chỉ mang lại lợi ích dễ đọc.
  • Chỉ hỗ trợ một giá trị cho mỗi loại bộ hạn định. Ví dụ: nếu muốn sử dụng cùng một tệp có thể vẽ cho Tây Ban Nha và Pháp, bạn không thể tạo thư mục có tên là drawable-es-fr/. Thay vào đó, bạn cần có 2 thư mục tài nguyên, chẳng hạn như drawable-es/drawable-fr/ chứa các tệp thích hợp. Tuy nhiên, bạn không cần phải sao chép các tệp ở cả hai vị trí. Thay vào đó, bạn có thể tạo một đại diện cho một tài nguyên, như mô tả trong phần Tạo tài nguyên đại diện.

Sau khi bạn lưu tài nguyên thay thế vào các thư mục được đặt tên bằng bộ hạn định này, Android sẽ tự động áp dụng các tài nguyên trong ứng dụng của bạn dựa trên cấu hình hiện tại của thiết bị. Mỗi khi có tài nguyên được yêu cầu, Android sẽ kiểm tra các thư mục tài nguyên thay thế xem có chứa tệp tài nguyên được yêu cầu hay không, sau đó tìm tài nguyên phù hợp nhất.

Nếu không có tài nguyên thay thế nào phù hợp với một cấu hình thiết bị cụ thể, thì Android sẽ sử dụng các tài nguyên mặc định tương ứng – nhóm tài nguyên cho một loại tài nguyên cụ thể không bao gồm bộ hạn định cấu hình.

Tạo tài nguyên đại diện

Khi có một tài nguyên mà bạn muốn sử dụng cho nhiều cấu hình thiết bị nhưng không muốn cung cấp ở dạng tài nguyên mặc định, bạn không cần phải đặt cùng một tài nguyên vào nhiều thư mục tài nguyên thay thế. Thay vào đó, bạn có thể tạo một tài nguyên thay thế đóng vai trò là đại diện cho một tài nguyên được lưu trong thư mục tài nguyên mặc định của bạn.

Lưu ý: Không phải tài nguyên nào cũng cung cấp cơ chế mà bạn có thể tạo đại diện cho tài nguyên khác. Cụ thể, ảnh động, trình đơn, dữ liệu thô và các tài nguyên không xác định khác trong thư mục xml/ không cung cấp tính năng này.

Ví dụ: giả sử bạn có biểu tượng ứng dụng icon.png và cần một phiên bản độc đáo cho các ngôn ngữ khác nhau. Tuy nhiên, 2 ngôn ngữ là Tiếng Anh-Canada và Tiếng Pháp-Canada cần sử dụng cùng một phiên bản. Bạn không cần sao chép cùng một hình ảnh vào thư mục tài nguyên cho cả tiếng Anh-Canada và tiếng Pháp-Canada. Thay vào đó, bạn có thể lưu hình ảnh dùng cho cả hai với bất kỳ tên nào không phải icon.png, chẳng hạn như icon_ca.png rồi đặt hình ảnh đó vào thư mục res/drawable/ mặc định. Sau đó, hãy tạo một tệp icon.xml trong res/drawable-en-rCA/res/drawable-fr-rCA/ tham chiếu đến tài nguyên icon_ca.png bằng cách sử dụng phần tử <bitmap>. Việc này cho phép bạn chỉ lưu trữ 1 phiên bản của tệp PNG và 2 tệp XML nhỏ trỏ đến tệp đó. Hãy xem ví dụ trong các phần sau để biết thông tin chi tiết.

Đối tượng có thể vẽ

Để tạo một đại diện cho một đối tượng có thể vẽ hiện có, hãy sử dụng phần tử <drawable>:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <drawable name="icon">@drawable/icon_ca</drawable>
</resources>

Nếu bạn lưu tệp này dưới dạng icon.xml trong một thư mục tài nguyên thay thế, chẳng hạn như res/values-en-rCA/, thì tài nguyên này sẽ được biên dịch thành tài nguyên mà bạn có thể tham chiếu dưới dạng R.drawable.icon, nhưng thực ra là đại diện của tài nguyên R.drawable.icon_ca được lưu trong res/drawable/.

Bố cục

Để tạo đại diện cho một bố cục hiện có, hãy sử dụng phần tử <include>, được gói trong một <merge>.

<?xml version="1.0" encoding="utf-8"?>
<merge>
    <include layout="@layout/main_ltr"/>
</merge>

Nếu bạn lưu tệp này dưới dạng main.xml, tệp này sẽ được biên dịch thành tài nguyên mà bạn có thể tham chiếu dưới dạng R.layout.main, nhưng thực ra là đại diện của tài nguyên R.layout.main_ltr.

Chuỗi và các giá trị đơn giản khác

Để tạo một đại diện cho một chuỗi hiện có, hãy sử dụng mã nhận dạng tài nguyên của chuỗi mong muốn làm giá trị cho chuỗi mới:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello</string>
    <string name="hi">@string/hello</string>
</resources>

Tài nguyên R.string.hi hiện là đại diện của R.string.hello.

Các giá trị đơn giản khác cũng hoạt động theo cách tương tự, chẳng hạn như màu:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="red">#f00</color>
    <color name="highlight">@color/red</color>
</resources>

Truy cập vào tài nguyên ứng dụng của bạn

Sau khi cung cấp tài nguyên trong ứng dụng, bạn có thể áp dụng tài nguyên đó bằng cách tham chiếu mã nhận dạng tài nguyên của tài nguyên đó. Mọi mã nhận dạng tài nguyên đều được xác định trong lớp R của dự án mà công cụ aapt sẽ tự động tạo.

Khi ứng dụng của bạn được biên dịch, aapt sẽ tạo lớp R, chứa mã nhận dạng tài nguyên cho mọi tài nguyên trong thư mục res/. Đối với mỗi loại tài nguyên, có một lớp con R, chẳng hạn như R.drawable cho mọi tài nguyên có thể vẽ. Mỗi tài nguyên thuộc loại đó đều có một số nguyên tĩnh, ví dụ: R.drawable.icon. Số nguyên này là mã nhận dạng tài nguyên mà bạn có thể dùng để truy xuất tài nguyên của mình.

Mặc dù lớp R là nơi có mã nhận dạng tài nguyên được chỉ định, nhưng bạn không cần phải tìm đến đó để khám phá mã nhận dạng tài nguyên. Mã nhận dạng tài nguyên luôn bao gồm các thành phần sau:

  • Loại tài nguyên: mỗi tài nguyên được nhóm thành một "loại", chẳng hạn như string, drawablelayout. Để biết thêm thông tin về các loại khác nhau, hãy xem bài viết Tổng quan về các loại tài nguyên.
  • Tên tài nguyên là tên tệp, không bao gồm đuôi tệp hoặc giá trị trong thuộc tính android:name XML, nếu tài nguyên là một giá trị đơn giản, chẳng hạn như một chuỗi.

Có 2 cách để bạn có thể truy cập vào tài nguyên:

  • Trong mã: sử dụng số nguyên tĩnh từ một lớp con của lớp R, chẳng hạn như:
    R.string.hello

    string là loại tài nguyên và hello là tên tài nguyên. Có nhiều API Android có thể truy cập vào tài nguyên của bạn khi bạn cung cấp mã nhận dạng tài nguyên ở định dạng này. Để biết thêm thông tin, hãy xem phần Truy cập vào tài nguyên trong mã.

  • Trong XML: sử dụng cú pháp XML đặc biệt cũng tương ứng với mã nhận dạng tài nguyên được xác định trong lớp R, chẳng hạn như:
    @string/hello

    string là loại tài nguyên và hello là tên tài nguyên. Bạn có thể sử dụng cú pháp này trong tài nguyên XML ở bất kỳ vị trí nào giá trị được mong đợi mà bạn cung cấp trong tài nguyên. Để biết thêm thông tin, hãy xem phần Truy cập vào tài nguyên từ XML.

Truy cập vào tài nguyên trong mã

Bạn có thể sử dụng tài nguyên trong mã bằng cách chuyển mã nhận dạng tài nguyên ở dạng tham số phương thức. Ví dụ: bạn có thể đặt ImageView để dùng tài nguyên res/drawable/myimage.png bằng cách sử dụng setImageResource():

Kotlin

val imageView = findViewById(R.id.myimageview) as ImageView
imageView.setImageResource(R.drawable.myimage)

Java

ImageView imageView = (ImageView) findViewById(R.id.myimageview);
imageView.setImageResource(R.drawable.myimage);

Bạn cũng có thể truy xuất từng tài nguyên riêng lẻ bằng các phương thức trong Resources. Bạn có thể lấy thực thể này của getResources().

Cú pháp

Dưới đây là cú pháp để tham chiếu một tài nguyên trong mã:

[<package_name>.]R.<resource_type>.<resource_name>
  • <package_name> là tên của gói chứa tài nguyên (không bắt buộc khi tham chiếu tài nguyên từ gói của bạn).
  • <resource_type> là lớp con R cho loại tài nguyên.
  • <resource_name> là tên tệp tài nguyên không có đuôi hoặc giá trị thuộc tính android:name trong phần tử XML, đối với các giá trị đơn giản.

Để biết thêm thông tin về từng loại tài nguyên và cách tham chiếu, hãy xem bài viết Tổng quan về các loại tài nguyên.

Trường hợp sử dụng

Có nhiều phương thức chấp nhận tham số mã nhận dạng tài nguyên và bạn có thể truy xuất các tài nguyên bằng các phương thức trong Resources. Bạn có thể tạo một thực thể của Resources bằng Context.getResources().

Sau đây là một số ví dụ về cách truy cập vào tài nguyên trong mã:

Kotlin

// Load a background for the current screen from a drawable resource.
window.setBackgroundDrawableResource(R.drawable.my_background_image)

// Set the Activity title by getting a string from the Resources object, because
//  this method requires a CharSequence rather than a resource ID.
window.setTitle(resources.getText(R.string.main_title))

// Load a custom layout for the current screen.
setContentView(R.layout.main_screen)

// Set a slide in animation by getting an Animation from the Resources object.
flipper.setInAnimation(AnimationUtils.loadAnimation(this,
        R.anim.hyperspace_in))

// Set the text on a TextView object using a resource ID.
val msgTextView = findViewById(R.id.msg) as TextView
msgTextView.setText(R.string.hello_message)

Java

// Load a background for the current screen from a drawable resource.
getWindow().setBackgroundDrawableResource(R.drawable.my_background_image) ;

// Set the Activity title by getting a string from the Resources object, because
//  this method requires a CharSequence rather than a resource ID.
getWindow().setTitle(getResources().getText(R.string.main_title));

// Load a custom layout for the current screen.
setContentView(R.layout.main_screen);

// Set a slide in animation by getting an Animation from the Resources object.
flipper.setInAnimation(AnimationUtils.loadAnimation(this,
        R.anim.hyperspace_in));

// Set the text on a TextView object using a resource ID.
TextView msgTextView = (TextView) findViewById(R.id.msg);
msgTextView.setText(R.string.hello_message);

Thận trọng: Không sửa đổi tệp R.java theo cách thủ công. Tệp này do công cụ aapt tạo khi biên dịch dự án của bạn. Mọi thay đổi sẽ được ghi đè vào lần biên dịch tiếp theo.

Truy cập vào tài nguyên từ XML

Bạn có thể xác định giá trị cho một số thành phần và thuộc tính XML bằng cách sử dụng tệp tham chiếu đến tài nguyên hiện có. Bạn thường thực hiện việc này khi tạo tệp bố cục để cung cấp các chuỗi và hình ảnh cho tiện ích của mình.

Ví dụ: nếu bạn thêm Button vào bố cục, hãy sử dụng tài nguyên chuỗi cho văn bản trên nút:

<Button
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/submit" />

Cú pháp

Dưới đây là cú pháp để tham chiếu một tài nguyên trong tài nguyên XML:

@[<package_name>:]<resource_type>/<resource_name>
  • <package_name> là tên của gói chứa tài nguyên (không bắt buộc khi tham chiếu tài nguyên từ cùng một gói).
  • <resource_type> là lớp con R cho loại tài nguyên.
  • <resource_name> là tên tệp tài nguyên không có đuôi hoặc giá trị thuộc tính android:name trong phần tử XML, đối với các giá trị đơn giản.

Để biết thêm thông tin về từng loại tài nguyên và cách tham chiếu, hãy xem bài viết Tổng quan về các loại tài nguyên.

Trường hợp sử dụng

Trong một số trường hợp, bạn phải sử dụng tài nguyên cho một giá trị trong XML (ví dụ: để áp dụng hình ảnh có thể vẽ cho tiện ích), nhưng bạn cũng có thể sử dụng tài nguyên trong XML ở bất kỳ nơi nào chấp nhận một giá trị đơn giản. Chẳng hạn, nếu bạn có tệp tài nguyên sau bao gồm một tài nguyên màu và một tài nguyên chuỗi:

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <color name="opaque_red">#f00</color>
   <string name="hello">Hello!</string>
</resources>

Bạn có thể sử dụng các tài nguyên này trong tệp bố cục sau để đặt màu văn bản và chuỗi văn bản:

<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:textColor="@color/opaque_red"
    android:text="@string/hello" />

Trong trường hợp này, bạn không cần chỉ định tên gói trong tệp tham chiếu tài nguyên, vì các tài nguyên có trong gói của bạn. Để tham chiếu tài nguyên hệ thống, bạn cần đưa tên gói vào, như minh hoạ trong ví dụ sau:

<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:textColor="@android:color/secondary_text_dark"
    android:text="@string/hello" />

Lưu ý: Luôn sử dụng tài nguyên chuỗi để có thể bản địa hoá ứng dụng cho các ngôn ngữ khác. Để biết thông tin về cách tạo tài nguyên thay thế (chẳng hạn như các chuỗi được bản địa hoá), hãy xem phần Cung cấp tài nguyên thay thế. Để xem hướng dẫn đầy đủ về cách bản địa hoá ứng dụng cho các ngôn ngữ khác, hãy xem bài viết Bản địa hoá ứng dụng.

Bạn thậm chí có thể sử dụng tài nguyên trong XML để tạo các đại diện. Chẳng hạn, bạn có thể tạo một tài nguyên có thể vẽ là đại diện của một tài nguyên có thể vẽ khác:

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/other_drawable" />

Điều này nghe có vẻ dư thừa, nhưng có thể rất hữu ích khi sử dụng tài nguyên thay thế. Để biết thêm thông tin, hãy xem phần tạo tài nguyên đại diện.

Thuộc tính kiểu tham chiếu

Tài nguyên thuộc tính kiểu cho phép bạn tham chiếu giá trị của một thuộc tính trong giao diện đang được áp dụng. Khi tham chiếu một thuộc tính kiểu, bạn có thể tuỳ chỉnh giao diện của các phần tử trên giao diện người dùng bằng cách tạo kiểu cho phù hợp với các biến thể tiêu chuẩn mà giao diện hiện tại cung cấp, thay vì cung cấp một giá trị được cố định trong mã. Việc tham chiếu một thuộc tính kiểu về cơ bản sẽ là "Sử dụng kiểu được xác định bằng thuộc tính này trong giao diện hiện tại".

Để tham chiếu một thuộc tính kiểu, cú pháp tên gần giống với định dạng tài nguyên thông thường, nhưng thay vì ký hiệu "at" (@), hãy sử dụng dấu chấm hỏi (?). Phần loại tài nguyên là không bắt buộc. Vì vậy, cú pháp tham chiếu sẽ như sau:

?[<package_name>:][<resource_type>/]<resource_name>

Ví dụ: dưới đây là cách bạn có thể tham chiếu một thuộc tính để đặt màu văn bản sao cho khớp với màu văn bản phụ của giao diện hệ thống:

<EditText id="text"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textColor="?android:textColorSecondary"
    android:text="@string/hello_world" />

Ở đây, thuộc tính android:textColor chỉ định tên của thuộc tính kiểu trong giao diện hiện tại. Android hiện sử dụng giá trị được áp dụng cho thuộc tính kiểu android:textColorSecondary làm giá trị cho android:textColor trong tiện ích này. Vì công cụ tài nguyên hệ thống biết rằng tài nguyên thuộc tính được mong đợi trong ngữ cảnh này, nên bạn không cần phải nêu rõ loại, đó là ?android:attr/textColorSecondary. Bạn có thể loại trừ loại attr.

Truy cập vào tệp gốc

Mặc dù không phổ biến, nhưng bạn có thể cần phải truy cập vào các tệp và thư mục gốc. Nếu truy cập vào thì bạn sẽ không thể lưu tệp trong res/, vì cách duy nhất để đọc tài nguyên từ res/ là dùng mã nhận dạng tài nguyên. Thay vào đó, bạn có thể lưu tài nguyên trong thư mục assets/.

Các tệp đã lưu trong thư mục assets/ không được cấp mã nhận dạng tài nguyên. Do đó, bạn không thể tham chiếu đến các tệp này thông qua lớp R hoặc từ tài nguyên XML. Thay vào đó, bạn có thể truy vấn các tệp trong thư mục assets/ như một hệ thống tệp thông thường và đọc dữ liệu thô bằng cách sử dụng AssetManager.

Tuy nhiên, nếu bạn chỉ cần đọc dữ liệu thô (chẳng hạn như tệp video hoặc âm thanh), thì hãy lưu tệp đó vào thư mục res/raw/ và đọc một luồng byte bằng openRawResource().

Truy cập vào tài nguyên của nền tảng

Android chứa một số tài nguyên chuẩn, chẳng hạn như kiểu, giao diện và bố cục. Để truy cập vào các tài nguyên này, hãy đáp ứng điều kiện về tham chiếu tài nguyên bằng tên gói android. Ví dụ: Android cung cấp tài nguyên bố cục mà bạn có thể sử dụng cho các mục danh sách trong ListAdapter:

Kotlin

listAdapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, myarray)

Java

setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myarray));

Trong ví dụ này, simple_list_item_1 là tài nguyên bố cục được nền tảng xác định cho các mục trong ListView. Bạn có thể sử dụng bố cục này thay vì tạo bố cục của riêng mình cho các mục danh sách.

Cung cấp khả năng tương thích tốt nhất với thiết bị bằng các tài nguyên

Để ứng dụng của bạn hỗ trợ nhiều cấu hình thiết bị, bạn phải luôn cung cấp tài nguyên mặc định cho mỗi loại tài nguyên mà ứng dụng của bạn dùng.

Ví dụ: nếu ứng dụng của bạn hỗ trợ nhiều ngôn ngữ, hãy luôn thêm thư mục values/ (nơi các chuỗi được lưu) không có bộ hạn định ngôn ngữ và khu vực. Thay vào đó, nếu bạn đặt mọi tệp chuỗi của mình vào thư mục có bộ hạn định ngôn ngữ và khu vực, thì ứng dụng sẽ gặp sự cố khi chạy trên thiết bị được đặt thành ngôn ngữ mà các chuỗi đó không hỗ trợ.

Miễn là bạn cung cấp tài nguyên values/ mặc định, thì ứng dụng sẽ chạy đúng cách, ngay cả khi người dùng không hiểu ngôn ngữ được hiển thị. Dù sao thì vẫn tốt hơn là gặp sự cố.

Tương tự, nếu cung cấp các tài nguyên bố cục khác nhau dựa vào hướng màn hình, bạn nên chọn một hướng làm hướng mặc định. Ví dụ: thay vì cung cấp tài nguyên bố cục trong layout-land/ cho chế độ ngang và layout-port/ cho chế độ dọc, hãy để một chế độ mặc định, chẳng hạn như layout/ cho chế độ ngang và layout-port/ cho chế độ dọc.

Việc cung cấp tài nguyên mặc định không chỉ quan trọng vì ứng dụng của bạn có thể chạy trên cấu hình ngoài dự kiến, mà còn vì các phiên bản Android mới đôi khi sẽ thêm những bộ hạn định cấu hình mà các phiên bản cũ không hỗ trợ. Nếu bạn sử dụng một bộ hạn định tài nguyên mới, nhưng vẫn duy trì khả năng tương thích mã với các phiên bản Android cũ hơn, thì khi phiên bản Android cũ chạy ứng dụng của bạn, ứng dụng đó sẽ gặp sự cố nếu bạn không cung cấp tài nguyên mặc định, vì ứng dụng không thể sử dụng tài nguyên có tên bộ hạn định mới.

Ví dụ: nếu minSdkVersion của bạn được đặt thành 4 và bạn đủ điều kiện dùng mọi tài nguyên có thể vẽ của mình bằng cách sử dụng chế độ ban đêm (night hoặc notnight đã được thêm vào API cấp 8), thì thiết bị API cấp 4 không thể truy cập vào các tài nguyên có thể vẽ của bạn và sẽ gặp sự cố. Trong trường hợp này, bạn có thể muốn notnight trở thành tài nguyên mặc định. Vì vậy, bạn nên loại trừ bộ hạn định đó để các tài nguyên có thể vẽ sẽ ở dạng drawable/ hoặc drawable-night/.

Tóm lại, để cung cấp khả năng tương thích tốt nhất với thiết bị, hãy luôn cung cấp tài nguyên mặc định cho các tài nguyên mà ứng dụng của bạn cần để có thể hoạt động đúng cách. Sau đó, hãy tạo tài nguyên thay thế cho các cấu hình thiết bị cụ thể bằng cách sử dụng bộ hạn định cấu hình.

Có một ngoại lệ đối với quy tắc này: Nếu minSdkVersion của ứng dụng là 4 trở lên, bạn không cần tài nguyên có thể vẽ mặc định khi cung cấp tài nguyên có thể vẽ thay thế với bộ hạn định mật độ màn hình. Ngay cả khi không có tài nguyên có thể vẽ mặc định, Android vẫn có thể tìm thấy kết quả phù hợp nhất trong số các mật độ màn hình thay thế và điều chỉnh bitmap theo tỷ lệ nếu cần. Tuy nhiên, để có trải nghiệm tốt nhất trên mọi loại thiết bị, hãy cung cấp các tài nguyên có thể vẽ thay thế cho cả 3 loại mật độ.

Cách Android tìm ra tài nguyên phù hợp nhất

Khi bạn yêu cầu một tài nguyên mà bạn cung cấp các tài nguyên thay thế, Android sẽ dựa vào cấu hình thiết bị hiện tại để chọn tài nguyên thay thế nhằm sử dụng trong thời gian chạy. Để minh hoạ cách Android chọn một tài nguyên thay thế, hãy giả sử mỗi thư mục có thể vẽ sau đây chứa các phiên bản khác nhau của cùng hình ảnh:

drawable/
drawable-en/
drawable-fr-rCA/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/

Đồng thời giả sử sau đây là cấu hình thiết bị:

Ngôn ngữ = en-GB
Hướng màn hình = port
Mật độ pixel màn hình = hdpi
Loại màn hình cảm ứng = notouch
Phương thức nhập văn bản chính = 12key

Bằng cách so sánh cấu hình thiết bị với tài nguyên thay thế có sẵn, Android sẽ chọn các đối tượng có thể vẽ từ drawable-en-port.

Hệ thống đưa ra quyết định về tài nguyên sẽ sử dụng với logic sau:

Hình 2. Sơ đồ quy trình về cách Android tìm được tài nguyên phù hợp nhất.

  1. Loại bỏ những tệp tài nguyên xung đột với cấu hình thiết bị.

    Thư mục drawable-fr-rCA/ bị loại bỏ vì thư mục này xung đột với ngôn ngữ en-GB.

    drawable/
    drawable-en/
    drawable-fr-rCA/
    drawable-en-port/
    drawable-en-notouch-12key/
    drawable-port-ldpi/
    drawable-port-notouch-12key/
    

    Ngoại lệ: Mật độ pixel trên màn hình là một bộ hạn định không bị loại bỏ do xung đột. Mặc dù mật độ màn hình của thiết bị là hdpi, nhưng drawable-port-ldpi/ sẽ không bị loại bỏ vì mọi mật độ màn hình đều được coi là khớp tại thời điểm này. Để biết thông tin, hãy xem bài viết Tổng quan về khả năng tương thích với màn hình.

  2. Tìm bộ hạn định có mức độ ưu tiên cao nhất tiếp theo trong danh sách (bảng 2). (Bắt đầu bằng MCC.)
  3. Có thư mục tài nguyên nào bao gồm bộ hạn định này không?
    • Nếu không, hãy quay lại bước 2 và xem bộ hạn định tiếp theo. Trong ví dụ này, câu trả lời là "không" cho đến khi câu trả lời là bộ hạn định ngôn ngữ.
    • Nếu có, hãy chuyển sang bước 4.
  4. Loại bỏ các thư mục tài nguyên không bao gồm bộ hạn định này. Trong ví dụ này, tiếp theo, hệ thống sẽ loại bỏ tất cả các thư mục không bao gồm bộ hạn định ngôn ngữ:
    drawable/
    drawable-en/
    drawable-en-port/
    drawable-en-notouch-12key/
    drawable-port-ldpi/
    drawable-port-notouch-12key/
    

    Ngoại lệ: Nếu bộ hạn định được đề cập trong câu hỏi là mật độ pixel trên màn hình, thì Android sẽ chọn lựa chọn phù hợp nhất với mật độ màn hình của thiết bị. Nhìn chung, Android muốn giảm kích thước hình ảnh gốc lớn hơn để mở rộng hình ảnh gốc nhỏ hơn. Để biết thêm thông tin, hãy xem bài viết Tổng quan về khả năng tương thích với màn hình.

  5. Lặp lại các bước 2, 3 và 4 cho đến khi chỉ còn một thư mục. Trong ví dụ này, hướng màn hình là bộ hạn định tiếp theo mà sẽ có bất kỳ kết quả trùng khớp nào. Do đó, những tài nguyên không chỉ định hướng màn hình sẽ bị loại bỏ:
    drawable-en/
    drawable-en-port/
    drawable-en-notouch-12key/
    

    Thư mục còn lại là drawable-en-port.

Mặc dù quy trình này được thực thi cho mỗi tài nguyên được yêu cầu, nhưng hệ thống sẽ tối ưu hoá một số khía cạnh của quy trình. Một trong những cách tối ưu hoá này là khi đã biết cấu hình của thiết bị, hệ thống có thể loại bỏ các tài nguyên thay thế không bao giờ khớp. Ví dụ: nếu ngôn ngữ cấu hình là tiếng Anh, thì mọi thư mục tài nguyên có bộ hạn định ngôn ngữ được đặt thành một ngôn ngữ khác tiếng Anh sẽ không bao giờ được đưa vào nhóm tài nguyên được đánh dấu (mặc dù thư mục tài nguyên không có bộ hạn định ngôn ngữ vẫn được bao gồm).

Khi chọn tài nguyên dựa trên bộ hạn định kích thước màn hình, hệ thống sẽ sử dụng tài nguyên được thiết kế cho một màn hình nhỏ hơn màn hình hiện tại nếu không có tài nguyên nào phù hợp hơn. Ví dụ: màn hình kích thước lớn sẽ sử dụng tài nguyên màn hình kích thước bình thường nếu cần.

Tuy nhiên, nếu tài nguyên duy nhất hiện có lớn hơn màn hình hiện tại, thì hệ thống sẽ không sử dụng các tài nguyên đó và ứng dụng của bạn sẽ gặp sự cố nếu không có tài nguyên nào khác khớp với cấu hình thiết bị. Ví dụ: sự cố này xảy ra nếu tất cả tài nguyên bố cục được gắn thẻ với bộ hạn định xlarge, nhưng thiết bị là màn hình có kích thước bình thường.

Lưu ý: Mức độ ưu tiên của bộ hạn định (trong bảng 2) quan trọng hơn số lượng bộ hạn định khớp chính xác với thiết bị. Trong ví dụ trước, ở bước 4, lựa chọn cuối cùng trong danh sách có 3 bộ hạn định khớp chính xác với thiết bị (hướng, loại màn hình cảm ứng và phương thức nhập), trong khi drawable-en chỉ có một tham số phù hợp (ngôn ngữ). Tuy nhiên, ngôn ngữ có mức độ ưu tiên cao hơn so với các bộ hạn định này, vì vậy drawable-port-notouch-12key sẽ bị loại bỏ.