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

Stay organized with collections Save and categorize content based on your preferences.

Tài nguyên (resource) là các tệp bổ sung và nội dung tĩnh mà 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.

Bạn phải 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 mã để có thể duy trì chúng một cách độc lập. Bạn cũng nên 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 chỉ cho bạn biết cách nhóm các tài nguyên trong dự án Android và 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ừ mã ứng dụng hoặc các tệp XML khác.

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

Bạn nên đặt mỗi loại tài nguyên trong 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

Như bạn có thể thấy trong ví dụ này, thư mục res/ chứa tất cả tài nguyên (trong thư mục con): 1 tài nguyên hình ảnh, 2 tài nguyên bố cục, thư mục mipmap/ cho các biểu tượng trình chạy và 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 hai loại.)
color/ Các tệp XML xác định danh sách trạng thái của màu. Xem Tài nguyên danh sách trạng thái màu
drawable/

Tệp Bitmap (.png, .9.png, .jpg, .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

Hãy xem mục Tài nguyên có thể vẽ.

mipmap/ Các tệp có thể vẽ cho các 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. Xem 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ụ. Xem Trình đơn tài nguyên.
raw/

Các tệp tuỳ ý để lưu ở dạng thô của các tệp này. Để 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 cần quyền truy cập vào tên tệp gốc và hệ phân cấp tệp, bạn có thể cân nhắc việc lưu một số tài nguyên trong thư mục assets/ (thay vì res/raw/). 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ụ: thành phần <string> tạo tài nguyên R.string và thành phần <color> tạo tài nguyên R.color.

Vì mỗi tài nguyên được xác định bằng thành phần XML riêng, nên bạn có thể tuỳ ý đặt tên cho tệp và đặt các loại tài nguyên khác nhau trong một tệp. Tuy nhiên, để đảm bảo 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 tên tệp cho những tài nguyên mà bạn có thể tạo trong thư mục này:

Xem Tài nguyên chuỗi, Tài nguyên kiểuCác loại tài nguyên khác.

xml/ Các 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 vào đây, chẳng hạn như cấu hình có thể tìm kiếm được.
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ưới dạng tài nguyên, hãy truy cập phần Phông chữ ở định dạng XML.

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

Để biết thêm thông tin về một số loại tài nguyên, vui lòng xem tài liệu về 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ụ: nếu thiết bị có màn hình lớn hơn bình thường, thì bạn nên cung cấp tài nguyên bố cục khác để tận dụng thêm không gian màn hình. Hoặc nếu một thiết bị có chế độ cài đặt ngôn ngữ khác, thì bạn nên 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. Để cung cấp các loại 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 mọi ứng dụng đều phải cung cấp tài nguyên thay thế để hỗ trợ các cấu hình cụ thể của thiết bị. Ví dụ: bạn nên thêm các tài nguyên có thể vẽ thay thế cho nhiều mật độ màn hình cũng như các 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ị khác nhau, mỗi thiết bị sử dụng tài nguyên bố cục khác nhau.

Cách chỉ định lựa chọn thay thế theo cấu hình cụ thể cho một nhóm tài nguyên:

  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 sai thứ tự của các bộ hạn định, thì các tài nguyên sẽ bị bỏ qua.

  2. Lưu các tài nguyên thay thế tương ứng 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 mỗi thư mục có thể vẽ này được định kích thước cho màn hình có độ phân giải cụ thể, nhưng tên tệp thì giống hệt nhau. Theo cách này, mã nhận dạng tài nguyên mà bạn sử dụng để tham chiếu hình ảnh icon.png hoặc background.png luôn giống nhau, nhưng Android sẽ 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 trường hợp ngoại lệ Resource Not Found khi người dùng thay đổi ngôn ngữ hệ thống mặc định.

Android hỗ trợ một số bộ hạn định cấu hình, và 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. Bảng 2 liệt kê các chuỗi định tính cấu hình hợp lệ theo thứ tự ưu tiên – nếu bạn 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 này.

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

Cấu hình Giá trị bộ hạn định Mô tả
MCC and MNC Ví dụ:
mcc310
mcc310-mnc004
mcc208-mnc00
, v.v.

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 (đ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). Nếu bạn chỉ cần chỉ định dựa trên ngôn ngữ, hãy sử 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) (sẽ thảo luận tiếp theo). Nếu quyết định sử dụng bộ hạn định MCC và MNC, bạn nên thận trọng và kiểm tra xem nó có hoạt động như mong đợi hay không.

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 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 hai chữ cái theo ISO 639-1, theo sau là mã vùng gồm hai chữ cái theo 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 một khu vực.

Android 7.0 (API cấp 24) đã giới thiệu tính năng hỗ trợ cho thẻ ngôn ngữ BCP 47. Bạn có thể sử 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. Xem phần Xử lý thay đổi thời gian chạy để 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.

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

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 các 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 muốn cung cấp một số bố cục cụ thể cho ngôn ngữ Ả Rập và một số bố cục chung cho ngôn ngữ "từ phải sang trái" nào khác (như tiếng Ba Tư hoặc tiếng Do Thái), bạn sẽ có bố cụ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.

smallestWidth (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 khu vực 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ể sử dụng bộ hạn định này để đảm bảo ứng dụng có chiều rộng tối thiểu là <N> dps cho giao diện người dùng của ứng dụng.

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ể sử dụng bộ hạn định res/layout-sw600dp/ này để tạo tài nguyên bố cục. 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 sẽ 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ố thành phần 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)
    • 480x800 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ư 480x800 mdpi (máy tính bảng/điện thoại di động).
  • 600, đối với màn hình như 600x1024 mdpi (máy tính bảng 7 inch).
  • 720, đối với màn hình như 720x1280 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 (kích thước màn hình có chiều rộng nhỏ nhất), hệ thống sẽ sử dụng giá trị gần nhất với chiều rộng nhỏ nhất 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, 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 bài viết Hỗ trợ các kích thước màn hình khác nhau.

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 các 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 (xem phần 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ó thành phần cố định trên giao diện người dùng ở các cạnh của 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(boolean) hoặc WindowCompat#setDecorFitsSystemWindows(Window,boolean).

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 và 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 sau cùng sẽ được chọn ngay cả tài nguyên trước đó 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 các màn hình khác nhau bằng bộ hạn định này, hãy xem bài viết Hỗ trợ các kích thước màn hình khác nhau.

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 320x426 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 320x470 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, 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 480x640 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 720x960 dp. Trong hầu hết các trường hợp, thiết bị có màn hình cực lớn sẽ quá lớn để có 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 sử 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ụ: 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ị thuộc loại màn hình có 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.

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

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 trên tỷ lệ khung hình của màn hình (màn hình "dài" 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: Hiển thị bằng một 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: Hiển thị với dải động cao
  • lowdr: Hiển thị với 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. Xem phần Xử lý thay đổi thời gian chạy để 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.

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" (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), chủ yếu được định hướng xung quanh DPAD 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 tai nghe 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 đế, vui lòng đọ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 cách sử dụng UiModeManager. Xem phần Xử lý thay đổi thời gian chạy để 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.

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. Xem phần Xử lý thay đổi thời gian chạy để 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.

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 120dpi.
  • mdpi: Màn hình có độ phân giải trung bình (trên HVGA truyền thống); khoảng 160dpi.
  • hdpi: Màn hình có độ phân giải cao; khoảng 240dpi.
  • xhdpi: Màn hình có độ phân giải cực cao; khoảng 320dpi. Đã 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 480dpi. Đã thêm vào API cấp 16
  • xxxhdpi: Sử dụng màn hình có độ phân giải cực cực cực cao (chỉ biểu tượng trình chạy, hãy xem ghi chú trong phần Hỗ trợ nhiều màn hình); khoảng 640dpi. Đã thêm vào API cấp 18
  • nodpi: Bạn có thể sử dụng tài nguyên này 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 213dpi. Đâ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 và hầu hết các ứng dụng không cần màn hình; chỉ cần cung cấp tài nguyên mdpi và hdpi là đủ cho hầu hết các ứng dụng, đồng thời hệ thống sẽ điều chỉnh màn hình theo tỷ lệ cho phù hợp. Đã thêm vào API cấp 13
  • anydpi: Bộ hạn định này khớp với tất cả các mật độ màn hình và được ưu tiên hơn các bộ hạn định khác. Điều 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. Bạn không nên dùng thuộc tính này trong hầu hết các trường hợp. Sử dụng nhóm mật độ chuẩn, giúp giảm đáng kể chi phí 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 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.

Nếu bạn chắc chắn tài nguyên hình ảnh trông chưa đủ đẹp trên TV hoặc trên các thiết bị khác và muốn thử các tài nguyên tvdpi, thì hệ số tỷ lệ sẽ là 1,33*mdpi. Ví dụ: hình ảnh 100px x 100px cho màn hình mdpi phải là 133px x 133px cho tvdpi.

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 các 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, hệ thống có thể sử dụng bất kỳ tài nguyên nào phù hợp nhất.

Hãy xem phần Hỗ trợ nhiều màn hình để 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 cho phù hợp với mật độ hiện tại.

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, cho dù thiết bị không bật bàn phím phần cứng. Nếu không có bàn phím phần mềm nào được cung cấp hoặc bàn phím phần mềm 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, dù bàn phím hiển thị 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. Xem phần Xử lý thay đổi thời gian chạy để 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.

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 dạng qwerty phần cứng, 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 dạng 12 phím phần cứng, 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). Vui lòng xem tài liệu về Cấp độ API Android để biết thêm thông tin về các giá trị này.

Lưu ý: Một số bộ hạn định cấu hình đã được thêm kể từ Android 1.0, vì vậy không phải mọi phiên bản Android đều hỗ trợ tất cả các bộ hạn định này. Việc sử dụng bộ hạn định mới ngầm thêm bộ hạn định phiên bản nền tảng để các thiết bị cũ chắc chắn 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 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. Ví dụ:
    • 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 được có res/drawable/drawable-en/.
  • 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ó hai 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ùng một 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. Vui lòng xem mục Tạo tài nguyên đại diện bên dưới.

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 (sẽ được thảo luận bên dưới). 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 các 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ưới 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 đó, (trong một số trường hợp), 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, hai 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 có thể giả định rằng bạn 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, nhưng điều này không đúng. Thay vào đó, bạn có thể lưu hình ảnh dùng cho cả hai dưới dạng icon_ca.png (bất kỳ tên nào khác ngoài icon.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>. Điều này cho phép bạn chỉ lưu trữ một phiên bản của tệp PNG và hai tệp XML nhỏ trỏ đến tệp đó. (Tệp XML mẫu được minh hoạ bên dưới.)

Tài nguyên 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>. Ví dụ:

<?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/), tài nguyên này được biên dịch thành một 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 trongres/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 bao bọc trong một <merge>. Ví dụ:

<?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ó, bạn chỉ cần 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. Ví dụ:

<?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ột 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 (ví dụ: R.drawable cho mọi tài nguyên có thể vẽ) 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 bao giờ 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:

  • 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 về các loại khác nhau, vui lòng xem 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ó hai cách để bạn có thể truy cập 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. Vui lòng 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. Vui lòng xem phần Truy cập 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 truyền mã nhận dạng tài nguyên dưới 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 thành phần XML (đối với các giá trị đơn giản).

Vui lòng xem Loại tài nguyên để biết thêm thông tin về từng loại tài nguyên và cách tham chiếu.

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 phiên bản của Resources bằng Context.getResources().

Sau đây là một số ví dụ về cách truy cập 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: Bạn không nên 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 sẽ thực hiện việc này khi tạo tệp bố cục để cung cấp chuỗi và hình ảnh cho tiện ích của bạn.

Ví dụ: nếu thêm một Button vào bố cục, bạn nên sử dụng tài nguyên chuỗi cho văn bả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 thành phần XML (đối với các giá trị đơn giản).

Vui lòng xem Loại tài nguyên để biết thêm thông tin về từng loại tài nguyên và cách tham chiếu.

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ì 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. Ví dụ:

<?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 ý: Bạn phải 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á), vui lòng xem bài viết 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, vui lòng xem nội dung Bản địa hoá.

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ế. Vui lòng đọc thêm về cách Tạo tài nguyên đại diện.

Tham chiếu các thuộc tính kiể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. Việc tham chiếu thuộc tính kiểu cho phép bạn tuỳ chỉnh giao diện của những thành phần 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 mã hoá cứng. Về cơ bản, việc tham chiếu đến một thuộc tính kiểu "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 (?) và phần loại tài nguyên là không bắt buộc. Ví dụ:

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

Ví dụ: dưới đây là cách bạn có thể tham chiếu đến 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 dưới dạng 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 xác định điều kiện 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 bạn cho các mục trong 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ị, điều rất quan trọng là 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/ (trong đó 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 tất cả các 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à chuỗi của bạn không hỗ trợ. Tuy nhiên, 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ữ đó thì vẫn tốt hơn so với việc 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 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/.

Vì vậy, để 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ể thực hiện đú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ị, bạn nên 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. Bạn có thể xem thêm thông tin trong tài liệu Hỗ trợ nhiều màn hình.

  2. Chọn 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 rồi di chuyển xuống.)
  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, 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 tuỳ 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. Vui lòng xem phần Hỗ trợ nhiều màn hình.

  5. Quay lại và 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á hơn nữa một số khía cạ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 ("en"), 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ụ: 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ị 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ị. Ví dụ: trong bước 4 trên, lựa chọn cuối cùng trong danh sách bao gồm 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ỏ.