Omówienie zasobów aplikacji

Zasoby to dodatkowe pliki i treści statyczne używane przez kod, takie jak mapy bitowe, definicje układu, ciągi tekstowe interfejsu użytkownika, instrukcje animacji i inne.

Zawsze wyodrębniaj z kodu zasoby aplikacji, takie jak obrazy i ciągi tekstowe, aby można było nimi zarządzać niezależnie. Możesz też udostępniać alternatywne zasoby dla konkretnych konfiguracji urządzeń, grupując je w katalogach zasobów o specjalnych nazwach. W czasie działania Android używa odpowiedniego zasobu na podstawie bieżącej konfiguracji. Możesz na przykład udostępniać inny układ interfejsu w zależności od rozmiaru ekranu lub inne ciągi znaków w zależności od ustawień języka.

Po wyodrębnieniu zasobów aplikacji możesz uzyskać do nich dostęp za pomocą identyfikatorów zasobów generowanych w klasie R projektu. Z tego dokumentu dowiesz się, jak grupować zasoby w projekcie aplikacji na Androida. Pokazuje też, jak udostępniać alternatywne zasoby dla określonych konfiguracji urządzeń, a następnie uzyskiwać do nich dostęp z kodu aplikacji lub innych plików XML.

Typy zasobów grupy

Umieść każdy typ zasobu w określonym podkatalogu katalogu res/ projektu. Oto na przykład hierarchia plików w prostym projekcie:

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

Katalog res/ zawiera wszystkie zasoby w podkatalogach: zasób obrazu, 2 zasoby layoutu, katalog mipmap/ z ikonami programu uruchamiającego i plik zasobu tekstowego. Nazwy katalogów zasobów są ważne i zostały opisane w tabeli 1.

Uwaga: więcej informacji o korzystaniu z folderów mipmap znajdziesz w artykule Umieszczanie ikon aplikacji w katalogach mipmap.

Tabela 1. Katalogi zasobów obsługiwane w katalogu projektu res/.

Katalog Typ zasobu
animator/ Pliki XML, które definiują animacje właściwości.
anim/ Pliki XML, które definiują animacje Tween. W tym katalogu można też zapisywać animacje właściwości, ale w przypadku animacji właściwości zalecany jest katalog animator/, aby odróżnić te 2 typy.
color/ Pliki XML, które definiują listę kolorów stanu. Więcej informacji znajdziesz w artykule Lista stanów kolorów.
drawable/

Pliki bitmapowe (PNG, .9.png, JPG lub GIF) lub pliki XML, które są kompilowane do tych podtypów obiektów rysowalnych:

  • Pliki bitmapowe
  • Pliki Nine-Patch (mapy bitowe o zmienianym rozmiarze)
  • Listy stanowe
  • Kształty
  • Rysunki animacji
  • Inne elementy rysowalne

Więcej informacji znajdziesz w artykule Zasoby rysowalne.

mipmap/ Pliki rysowalne dla różnych gęstości ikon programu uruchamiającego. Więcej informacji o zarządzaniu ikonami programu uruchamiającego za pomocą folderów mipmap/ znajdziesz w artykule Umieszczanie ikon aplikacji w katalogach mipmap.
layout/ Pliki XML, które definiują układ interfejsu użytkownika. Więcej informacji znajdziesz w artykule Zasób layoutu.
menu/ Pliki XML, które definiują menu aplikacji, np. menu opcji, menu kontekstowe lub podmenu. Więcej informacji znajdziesz w artykule Zasób menu.
raw/

dowolne pliki, które mają być zapisane w formie nieprzetworzonej; Aby otworzyć te zasoby za pomocą funkcji raw InputStream, wywołaj funkcję call Resources.openRawResource() z identyfikatorem zasobu, czyli R.raw.filename.

Jeśli jednak potrzebujesz dostępu do oryginalnych nazw plików i hierarchii plików, rozważ zapisanie zasobów w katalogu assets/ zamiast w res/raw/. Pliki w assets/ nie mają identyfikatora zasobu, więc można je odczytać tylko za pomocą AssetManager.

values/

Pliki XML zawierające proste wartości, takie jak ciągi znaków, liczby całkowite i kolory.

Pliki zasobów XML w innych podkatalogach res/ definiują pojedynczy zasób na podstawie nazwy pliku XML, natomiast pliki w katalogu values/ opisują wiele zasobów. W przypadku pliku w tym katalogu każdy element podrzędny elementu <resources> definiuje pojedynczy zasób. Na przykład element <string> tworzy zasób R.string, a element <color> tworzy zasób R.color.

Każdy zasób jest zdefiniowany za pomocą własnego elementu XML, więc możesz nazwać plik dowolnie i umieścić w nim różne typy zasobów. Dla przejrzystości możesz jednak umieścić unikalne typy zasobów w różnych plikach. Oto na przykład konwencje nazewnictwa plików zasobów, które możesz utworzyć w tym katalogu:

Więcej informacji znajdziesz w sekcjach Zasoby tekstowe, Zasoby styluWięcej typów zasobów.

xml/ Dowolne pliki XML, które można odczytać w czasie działania programu, wywołując funkcję Resources.getXML(). Musisz tu zapisać różne pliki konfiguracji XML, np. konfigurację wyszukiwania.
font/ Pliki czcionek z rozszerzeniami TTF, OTF lub TTC albo pliki XML zawierające element <font-family>. Więcej informacji o czcionkach jako zasobach znajdziesz w artykule Dodawanie czcionki jako zasobu XML.

Uwaga: nigdy nie zapisuj plików zasobów bezpośrednio w katalogu res/. Powoduje to błąd kompilatora.

Więcej informacji o poszczególnych typach zasobów znajdziesz w przeglądzie typów zasobów.

Zasoby zapisane w podkatalogach zdefiniowanych w tabeli 1 są zasobami domyślnymi. Oznacza to, że te zasoby określają domyślny wygląd i treści aplikacji. Jednak różne typy urządzeń z Androidem mogą wymagać różnych typów zasobów.

Możesz na przykład udostępnić różne zasoby układu dla urządzeń z większymi niż zwykle ekranami, aby wykorzystać dodatkową przestrzeń. Możesz też udostępnić różne zasoby ciągów znaków, które tłumaczą tekst w interfejsie użytkownika na podstawie ustawień języka urządzenia. Aby udostępniać różne zasoby dla różnych konfiguracji urządzeń, musisz podać zasoby alternatywne oprócz zasobów domyślnych.

Podawanie zasobów alternatywnych

Większość aplikacji udostępnia alternatywne zasoby, które obsługują określone konfiguracje urządzeń. Na przykład dodaj alternatywne zasoby rysowalne dla różnych gęstości ekranu i alternatywne zasoby ciągów tekstowych dla różnych języków. W czasie działania Android wykrywa bieżącą konfigurację urządzenia i wczytuje odpowiednie zasoby dla aplikacji.

Rysunek 1. Dwa urządzenia korzystające z różnych zasobów układu w zależności od rozmiaru ekranu.

Aby określić alternatywne wersje zasobów dla konkretnej konfiguracji:

  1. Utwórz w folderze res/ nowy katalog o nazwie w formacie <resources_name>-<qualifier>.
    • <resources_name> to nazwa katalogu odpowiednich domyślnych zasobów (zdefiniowanych w tabeli 1).
    • <qualifier> to nazwa określająca indywidualną konfigurację, w której mają być używane te zasoby (zdefiniowane w tabeli 2).

    Możesz dołączyć więcej niż jeden <qualifier>. Oddzielaj je od siebie myślnikami.

    Ostrzeżenie: jeśli dodajesz kilka kwalifikatorów, musisz je umieścić w tej samej kolejności, w jakiej są wymienione w tabeli 2. Jeśli kwalifikatory są uporządkowane nieprawidłowo, zasoby są ignorowane.

  2. Zapisz odpowiednie zasoby alternatywne w tym nowym katalogu. Pliki zasobów muszą mieć dokładnie takie same nazwy jak domyślne pliki zasobów.

Oto przykładowe zasoby domyślne i alternatywne:

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

Kwalifikator hdpi oznacza, że zasoby w tym katalogu są przeznaczone dla urządzeń z ekranem o wysokiej gęstości pikseli. Obrazy w tych katalogach obiektów rysowalnych są dostosowane do określonych gęstości ekranu, ale nazwy plików są dokładnie takie same. Dzięki temu identyfikator zasobu, którego używasz do odwoływania się do obrazu icon.png lub background.png, jest zawsze taki sam. Android wybiera wersję każdego zasobu, która najlepiej pasuje do bieżącego urządzenia, porównując informacje o konfiguracji urządzenia z kwalifikatorami w nazwie katalogu zasobów.

Ostrzeżenie: podczas definiowania zasobu alternatywnego upewnij się, że zdefiniowano go również w konfiguracji domyślnej. W przeciwnym razie, gdy urządzenie zmieni konfigurację, w aplikacji mogą wystąpić wyjątki w czasie działania. Jeśli na przykład dodasz ciąg znaków tylko do values-en, a nie do values, aplikacja może napotkać wyjątek Resource Not Found, gdy użytkownik zmieni domyślny język systemu.

W tabeli 2 podano prawidłowe kwalifikatory konfiguracji w kolejności ich ważności. Do nazwy katalogu możesz dodać kilka kwalifikatorów, rozdzielając je myślnikami. Jeśli używasz wielu kwalifikatorów w przypadku katalogu zasobów, musisz dodać je do nazwy katalogu w kolejności, w jakiej są wymienione w tabeli.

Tabela 2. Nazwy kwalifikatorów konfiguracji.

Konfiguracja Wartości kwalifikatora Opis
MCC i MNC Przykłady:
mcc310
mcc310-mnc004
mcc208-mnc00

Kod kraju sieci komórkowej (MCC), opcjonalnie z kodem MNC z karty SIM w urządzeniu. Na przykład mcc310 oznacza Stany Zjednoczone w przypadku dowolnego operatora, mcc310-mnc004 – Stany Zjednoczone w przypadku Verizon, a mcc208-mnc00 – Francję w przypadku Orange.

Jeśli urządzenie korzysta z połączenia radiowego (czyli jest telefonem GSM), wartości MCC i MNC pochodzą z karty SIM.

Możesz też użyć samego kodu MCC, np. aby uwzględnić w aplikacji zasoby prawne dotyczące danego kraju. Jeśli chcesz określić tylko język, użyj kwalifikatora język, pismo (opcjonalnie) i region (opcjonalnie). Jeśli używasz kwalifikatora MCC i MNC, rób to ostrożnie i sprawdź, czy działa on zgodnie z oczekiwaniami.

Zobacz też pola konfiguracji mccmnc, które wskazują odpowiednio bieżący mobile country code i kod MNC.

Język, pismo (opcjonalnie) i region (opcjonalnie) Przykłady:
en
fr
en-rUS
fr-rFR
fr-rCA
b+en
b+en+US
b+es+419
b+zh+Hant
b+sr+Latn+RS

Język jest określany przez dwuliterowy kod języka ISO 639-1, po którym opcjonalnie może występować dwuliterowy kod regionu ISO 3166-1-alpha-2 (poprzedzony małą literą r).

W kodach nie jest rozróżniana wielkość liter. Prefiks r służy do odróżnienia części regionu. Nie możesz określić samego regionu.

W Androidzie 7.0 (interfejs API na poziomie 24) wprowadzono obsługę tagów języka zgodnych ze standardem BCP 47, których możesz używać do kwalifikowania zasobów specyficznych dla danego języka i regionu. Tag języka składa się z ciągu co najmniej 1 podtagu, z których każdy doprecyzowuje lub zawęża zakres języka identyfikowanego przez cały tag. Więcej informacji o tagach językowych znajdziesz w artykule Tagi do identyfikowania języków.

Aby użyć tagu języka BCP 47, połącz znak b+ z dwuliterowym kodem języka ISO 639-1. Opcjonalnie możesz dodać kolejne tagi podrzędne rozdzielone znakiem +.

Tag języka może się zmieniać w trakcie działania aplikacji, jeśli użytkownicy zmienią język w ustawieniach systemu. Więcej informacji o tym, jak może to wpłynąć na aplikację w czasie działania, znajdziesz w artykule Obsługa zmian konfiguracji.

Pełny przewodnik po lokalizowaniu aplikacji na inne języki znajdziesz w artykule Lokalizowanie aplikacji.

Zobacz też metodę getLocales(), która zawiera zdefiniowaną listę języków. Ta lista zawiera język podstawowy.

Rodzaj gramatyczny masculine
feminine
neuter

Rodzaj gramatyczny użytkownika. Używane w przypadku języków, w których występuje rodzaj gramatyczny.

Jeśli na przykład chcesz udostępniać różne zasoby użytkownikom posługującym się językiem francuskim, możesz użyć katalogów takich jak te:

res/
  values-fr/
    strings.xml (domyślne ciągi znaków z nieokreśloną płcią)
  values-fr-masculine/
    strings.xml (ciągi znaków z rodzajem męskim)
  values-fr-feminine/
    strings.xml (ciągi znaków z rodzajem żeńskim)
  values-fr-neuter/
    strings.xml (ciągi znaków z rodzajem nijakim)

Zobacz: Rodzaj gramatyczny w Androidzie.

Zobacz też metodę konfiguracji getGrammaticalGender(), która wskazuje rodzaj gramatyczny.

Dodano na poziomie API 34.

Kierunek układu ldrtl
ldltr

Kierunek układu aplikacji. ldrtl oznacza „layout-direction-right-to-left”. ldltr oznacza „layout-direction-left-to-right” i jest domyślną wartością niejawną.

Może to dotyczyć dowolnego zasobu, np. układów, elementów rysowalnych lub wartości.

Jeśli na przykład chcesz udostępnić konkretny układ dla języka arabskiego i ogólny układ dla dowolnego innego języka zapisanego od prawej do lewej, takiego jak perski czy hebrajski, użyj katalogów w tym formacie:

res/
  layout/
    main.xml (układ domyślny)
  layout-ar/
    main.xml (układ specjalny dla języka arabskiego)
  layout-ldrtl/
    main.xml (dowolny język zapisywany od prawej do lewej z wyjątkiem arabskiego, ponieważ kwalifikator języka „ar” ma wyższy priorytet)

Uwaga: aby włączyć w aplikacji funkcje układu od prawej do lewej, musisz ustawić wartość SupportsRtl na "true" i wartość TargetSdkVersion na 17 lub wyższą.

Dodano na poziomie API 17.

Najmniejsza szerokość sw<N>dp

Przykłady:
sw320dp
sw600dp
sw720dp
itd.

Najkrótszy wymiar obszaru ekranu dostępnego dla aplikacji. W szczególności smallestWidth okna aplikacji to najkrótszy z dostępnych wymiarów wysokości i szerokości okna. Możesz też myśleć o niej jako o „najmniejszej możliwej szerokości” okna. Możesz użyć tego kwalifikatora, aby interfejs aplikacji miał szerokość co najmniej <N> dp.

Jeśli na przykład układ wymaga, aby jego najmniejszy wymiar obszaru ekranu wynosił co najmniej 600 dp, możesz użyć tego kwalifikatora, aby utworzyć zasoby układu w katalogu res/layout-sw600dp/. System korzysta z tych zasobów tylko wtedy, gdy najmniejszy wymiar dostępnego ekranu ma co najmniej 600 dp, niezależnie od tego, czy ten wymiar jest postrzeganą przez użytkownika wysokością czy szerokością. Najmniejsza szerokość może się zmienić, jeśli rozmiar okna zostanie zmieniony, co spowoduje zmianę dostępnej szerokości lub wysokości, albo jeśli okno zostanie przeniesione, co może spowodować zmianę marginesów systemowych.

Używanie najmniejszej szerokości do określania ogólnego rozmiaru ekranu jest przydatne, ponieważ szerokość jest często czynnikiem decydującym o projektowaniu układu. Interfejs użytkownika często przewija się w pionie, ale ma dość duże ograniczenia dotyczące minimalnej przestrzeni potrzebnej w poziomie.

Dostępna szerokość jest też kluczowym czynnikiem przy określaniu, czy używać układu z 1 panelem na telefonach, czy układu z wieloma panelami na tabletach. Dlatego prawdopodobnie najbardziej zależy Ci na tym, aby poznać najmniejszą możliwą szerokość na każdym urządzeniu.

Najmniejsza szerokość urządzenia uwzględnia dekoracje ekranu i interfejs systemu. Jeśli na przykład urządzenie ma na ekranie stałe elementy interfejsu, które zajmują miejsce wzdłuż osi o najmniejszej szerokości, system deklaruje, że najmniejsza szerokość jest mniejsza niż rzeczywisty rozmiar ekranu, ponieważ są to piksele ekranu niedostępne dla interfejsu.

Oto niektóre wartości, których możesz użyć w przypadku typowych rozmiarów ekranu:

  • 320 – w przypadku urządzeń o konfiguracji ekranu takiej jak:
    • 240 x 320 ldpi (telefon QVGA)
    • 320 x 480 mdpi (telefon)
    • 480x800 hdpi (urządzenie o dużej gęstości)
  • 480 – w przypadku ekranów takich jak 480 x 800 mdpi (tablet/telefon);
  • 600 – w przypadku ekranów takich jak 600 x 1024 mdpi (7-calowy tablet).
  • 720 – w przypadku ekranów takich jak 720 x 1280 mdpi (10-calowy tablet).

Jeśli aplikacja udostępnia wiele katalogów zasobów z różnymi wartościami kwalifikatora smallestWidth, system używa tego, który jest najbliższy (ale nie przekracza) wartości smallestWidth urządzenia.

Dodano na poziomie API 13.

Zobacz też atrybut android:requiresSmallestWidthDp, który deklaruje minimalną wartość smallestWidth, z którą Twoja aplikacja jest zgodna, oraz pole konfiguracji smallestScreenWidthDp, które zawiera wartość smallestWidth urządzenia.

Więcej informacji o projektowaniu na różne ekrany za pomocą tego kwalifikatora znajdziesz w artykule Projektowanie elastyczne i adaptacyjne z użyciem widoków.

Dostępna szerokość i wysokość w<N>dp
h<N>dp

Przykłady:
w720dp
w1024dp
h720dp
h1024dp
itp.

Określa minimalną dostępną szerokość lub wysokość ekranu (w dp jednostkach zdefiniowanych przez wartość <N>), przy której używany jest zasób. Te wartości konfiguracji są porównywane z bieżącą szerokością i wysokością wyświetlacza, gdy urządzenie zmienia orientację z pionowej na poziomą lub odwrotnie, składa się lub rozkłada albo system wchodzi w tryb wielu okien lub z niego wychodzi. W trybie wielu okien wartości odzwierciedlają szerokość i wysokość okna zawierającego aplikację, a nie szerokość i wysokość ekranu urządzenia. Podobnie w przypadku aktywności osadzonych wartości dotyczą szerokości i wysokości poszczególnych aktywności, a nie szerokości i wysokości ekranu. Więcej informacji znajdziesz w sekcji Osadzanie aktywności.

Dostępna szerokość i wysokość często przydają się do określania, czy używać układu wielopanelowego, ponieważ nawet na tablecie nie zawsze chcesz używać tego samego układu wielopanelowego w orientacji pionowej i poziomej. Dlatego możesz ich używać do określania minimalnej szerokości lub wysokości wymaganej w przypadku układu zamiast używać razem kwalifikatorów rozmiaru ekranu i orientacji.

Jeśli aplikacja udostępnia wiele katalogów zasobów z różnymi wartościami dla tych konfiguracji, system używa tego, który jest najbliższy (bez przekraczania) bieżącej szerokości ekranu urządzenia. Najbliższy jest określany przez dodanie różnic między rzeczywistą szerokością ekranu a określoną szerokością do różnicy między rzeczywistą wysokością ekranu a określoną wysokością. Nieokreślone wysokości i szerokości mają wartość 0.

Wartości nie obejmują obszaru zajmowanego przez wstawki okna, więc jeśli urządzenie ma trwałe elementy interfejsu u krawędzi wyświetlacza, wartości szerokości i wysokości są mniejsze niż rzeczywiste wymiary ekranu, nawet gdy aplikacja jest wyświetlana od krawędzi do krawędzi za pomocą Window.setDecorFitsSystemWindows lub WindowCompat.setDecorFitsSystemWindows.

Niektóre dekoracje ekranu w orientacji pionowej, które nie są stałe (np. pasek stanu telefonu, który można ukryć w trybie pełnoekranowym), nie są tu uwzględniane. Nie są też uwzględniane dekoracje okien, takie jak pasek tytułu czy pasek działań, więc aplikacje muszą być przygotowane na nieco mniejszą przestrzeń niż ta, którą określają.

Uwaga: system wybiera zasób, który pasuje zarówno pod względem szerokości, jak i wysokości. Dlatego zasób, który określa oba te elementy, jest znacznie lepszy od zasobu, który określa tylko jeden z nich. Jeśli na przykład rzeczywista szerokość ekranu wynosi 720 dp, a wysokość – 1280 dp, a jeden zasób ma kwalifikator w720dp, a drugi – w700dp-h1200dp, zostanie wybrany ten drugi, mimo że pierwszy jest dokładnym dopasowaniem do określonych przez niego wartości.

Dodano na poziomie API 13.

Zobacz też pola konfiguracji screenWidthDpscreenHeightDp, które zawierają bieżącą szerokość i wysokość ekranu.

Więcej informacji o projektowaniu na różne ekrany za pomocą tego kwalifikatora znajdziesz w artykule Projektowanie elastyczne i adaptacyjne z użyciem widoków.

Rozmiar ekranu small
normal
large
xlarge
  • small: ekrany o rozmiarach podobnych do ekranu QVGA o niskiej gęstości pikseli. Minimalny rozmiar układu na małym ekranie to około 320 x 426 dp. Przykłady to QVGA o niskiej gęstości i VGA o wysokiej gęstości.
  • normal:ekrany o rozmiarach podobnych do ekranu HVGA o średniej gęstości pikseli. Minimalny rozmiar układu na normalnym ekranie to około 320 x 470 dp. Przykłady takich ekranów to WQVGA o niskiej gęstości, HVGA o średniej gęstości i WVGA o wysokiej gęstości.
  • large: ekrany o rozmiarach podobnych do ekranu VGA o średniej gęstości pikseli. Minimalny rozmiar układu na dużym ekranie to około 480 x 640 dp. Przykłady to ekrany VGA i WVGA o średniej gęstości.
  • xlarge: ekrany znacznie większe niż tradycyjny ekran HVGA o średniej gęstości pikseli. Minimalny rozmiar układu na ekranie o rozmiarze xlarge to około 720 x 960 dp. W większości przypadków urządzenia z bardzo dużymi ekranami są za duże, aby nosić je w kieszeni, i najprawdopodobniej są to urządzenia typu tablet. Dodano na poziomie API 9.

Uwaga: użycie kwalifikatora rozmiaru nie oznacza, że zasoby są przeznaczone tylko na ekrany o tym rozmiarze. Jeśli nie podasz zasobów alternatywnych z kwalifikatorami, które lepiej pasują do bieżącej konfiguracji urządzenia, system może użyć dowolnych zasobów, które najlepiej pasują.

Ostrzeżenie: jeśli wszystkie zasoby używają kwalifikatora rozmiaru, który jest większy niż bieżący ekran, system nie ich używa, a aplikacja ulega awarii w czasie działania. Dzieje się tak na przykład, gdy wszystkie zasoby układu są oznaczone kwalifikatorem xlarge, ale urządzenie ma ekran o normalnym rozmiarze.

Dodano na poziomie API 4.

Zobacz też pole konfiguracji screenLayout, które wskazuje, czy ekran jest mały, normalny czy duży.

Więcej informacji znajdziesz w omówieniu zgodności ekranów.

Format ekranu long
notlong
  • long: długie ekrany, np. WQVGA, WVGA, FWVGA
  • notlong: nie są to ekrany o wydłużonym kształcie, takie jak QVGA, HVGA i VGA.

Dodano na poziomie API 4.

Zależy to wyłącznie od formatu ekranu (ekran long jest szerszy). Nie ma to związku z orientacją ekranu.

Zobacz też pole konfiguracji screenLayout, które wskazuje, czy ekran jest długi.

Okrągły ekran round
notround
  • round: okrągłe ekrany, np. okrągłe urządzenia do noszenia;
  • notround: ekrany prostokątne, np. telefony lub tablety;

Dodano na poziomie interfejsu API 23.

Zobacz też metodę konfiguracji isScreenRound(), która określa, czy ekran jest okrągły.

Szeroka gama kolorów widecg
nowidecg
  • widecg: wyświetlacze z szeroką gamą kolorów, np. Display P3 lub AdobeRGB.
  • nowidecg: wyświetlacze z wąską gamą kolorów, np. sRGB;

Dodano na poziomie interfejsu API 26.

Zobacz też metodę isScreenWideColorGamut() konfiguracji, która wskazuje, czy ekran ma szeroką gamę kolorów.

HDR (High Dynamic Range) highdr
lowdr
  • highdr: wyświetlacze o wysokim zakresie dynamiki,
  • lowdr: wyświetlacze o niskim lub standardowym zakresie dynamicznym,

Dodano na poziomie interfejsu API 26.

Zobacz też metodę isScreenHdr() konfiguracji, która wskazuje, czy ekran obsługuje HDR.

Orientacja ekranu port
land
  • port: urządzenie jest w orientacji pionowej;
  • land: urządzenie jest w orientacji poziomej;

Może się to zmienić w trakcie działania aplikacji, jeśli użytkownik obróci ekran. Więcej informacji o tym, jak wpływa to na aplikację w czasie działania, znajdziesz w artykule Obsługa zmian konfiguracji.

Zobacz też pole konfiguracji orientation, które wskazuje bieżącą orientację urządzenia.

Tryb interfejsu car
desk
television
appliance
watch
vrheadset
  • car: urządzenie jest umieszczone w samochodowej stacji dokującej;
  • desk: urządzenie jest umieszczone w stacji dokującej na biurko;
  • television: urządzenie wyświetla obraz na telewizorze, zapewniając „10-stopową” wygodę, w której interfejs użytkownika jest wyświetlany na dużym ekranie, od którego użytkownik jest oddalony, a korzystanie z urządzenia odbywa się głównie za pomocą pada kierunkowego lub innych elementów sterujących niewymagających wskaźnika.
  • appliance: urządzenie pełni funkcję sprzętu AGD bez wyświetlacza.
  • watch: urządzenie ma wyświetlacz i jest noszone na nadgarstku.
  • vrheadset: urządzenie wyświetla obraz w goglach do rzeczywistości wirtualnej

Dodano na poziomie API 8; telewizor dodano na poziomie API 13; zegarek dodano na poziomie API 20.

Informacje o tym, jak aplikacja może reagować na włożenie urządzenia do stacji dokującej lub wyjęcie go z niej, znajdziesz w artykule Określanie i monitorowanie stanu i typu stacji dokującej.

Może się to zmienić w trakcie działania aplikacji, jeśli użytkownik umieści urządzenie w stacji dokującej. Niektóre z tych trybów możesz włączać i wyłączać za pomocą pola UiModeManager. Więcej informacji o tym, jak to wpływa na aplikację w czasie działania, znajdziesz w artykule Obsługa zmian konfiguracji.

Tryb nocny night
notnight
  • night: noc
  • notnight: w ciągu dnia

Dodano na poziomie API 8.

Może się to zmienić w trakcie działania aplikacji, jeśli tryb nocny pozostanie w trybie automatycznym (domyślnym), w którym to przypadku tryb zmienia się w zależności od pory dnia. Możesz włączyć lub wyłączyć ten tryb za pomocą ikony UiModeManager. Więcej informacji o tym, jak wpływa to na aplikację w czasie działania, znajdziesz w artykule Obsługa zmian konfiguracji.

Gęstość pikseli na ekranie (dpi) ldpi
mdpi
hdpi
xhdpi
xxhdpi
xxxhdpi
nodpi
tvdpi
anydpi
nnndpi
  • ldpi: ekrany o niskiej gęstości, ok. 120 dpi.
  • mdpi: ekrany o średniej gęstości (tradycyjne ekrany HVGA); około 160 dpi.
  • hdpi: ekrany o wysokiej gęstości pikseli, ok. 240 dpi.
  • xhdpi: ekrany o bardzo wysokiej gęstości, ok. 320 dpi. Dodano w API na poziomie 8.
  • xxhdpi: ekrany o bardzo wysokiej gęstości pikseli, około 480 dpi. Dodano w interfejsie API na poziomie 16.
  • xxxhdpi: bardzo wysoka gęstość pikseli (tylko ikona programu uruchamiającego – patrz Obsługa różnych gęstości pikseli); około 640 dpi. Dodano na poziomie API 18.
  • nodpi: używany w przypadku zasobów bitmapowych, które nie mają być skalowane w celu dopasowania do gęstości urządzenia.
  • tvdpi: ekrany o rozdzielczości między mdpi a hdpi, czyli około 213 dpi. Nie jest to „podstawowa” grupa gęstości. Jest on przeznaczony głównie dla telewizorów o rozdzielczości 720p i nie jest potrzebny w większości aplikacji. W przypadku paneli telewizorów 1080p użyj xhdpi, a w przypadku paneli telewizorów 4K użyj xxxhdpi. Dodano na poziomie API 13.
  • anydpi: pasuje do wszystkich gęstości ekranu i ma pierwszeństwo przed innymi kwalifikatorami. Jest to przydatne w przypadku rysunków wektorowych. Dodano na poziomie API 21.
  • nnndpi: używany do reprezentowania niestandardowych gęstości, gdzie nnn to dodatnia liczba całkowita określająca gęstość ekranu. W większości przypadków nie jest to używane. Korzystanie ze standardowych zakresów gęstości znacznie zmniejsza nakład pracy związany z obsługą różnych gęstości ekranów urządzeń dostępnych na rynku.

Między 6 głównymi gęstościami (z wyłączeniem gęstości tvdpi) występuje współczynnik skalowania 3:4:6:8:12:16. Bitmapa 9x9 w rozdzielczości ldpi ma wymiary 12x12 w rozdzielczości mdpi, 18x18 w rozdzielczości hdpi, 24x24 w rozdzielczości xhdpi itd.

Uwaga: użycie kwalifikatora gęstości nie oznacza, że zasoby są przeznaczone tylko na ekrany o tej gęstości. Jeśli nie podasz alternatywnych zasobów z kwalifikatorami, które lepiej pasują do bieżącej konfiguracji urządzenia, system użyje zasobów, które są najlepiej dopasowane.

Więcej informacji o obsłudze różnych gęstości ekranu i o tym, jak Android może skalować mapy bitowe, aby dopasować je do bieżącej gęstości, znajdziesz w artykule Omówienie zgodności z ekranami.

Typ ekranu dotykowego notouch
finger
  • notouch: urządzenie nie ma ekranu dotykowego.
  • finger: urządzenie ma ekran dotykowy, który jest przeznaczony do bezpośredniej interakcji z użyciem palca użytkownika.

Zobacz też pole konfiguracji touchscreen, które wskazuje typ ekranu dotykowego na urządzeniu.

Dostępność klawiatury keysexposed
keyshidden
keyssoft
  • keysexposed: urządzenie ma dostępną klawiaturę. Jeśli na urządzeniu jest włączona klawiatura programowa (co jest prawdopodobne), jest ona używana nawet wtedy, gdy klawiatura sprzętowa nie jest dostępna dla użytkownika lub gdy urządzenie nie ma klawiatury sprzętowej. Jeśli klawiatura programowa nie jest dostępna lub jest wyłączona, ta opcja jest używana tylko wtedy, gdy jest dostępna klawiatura sprzętowa.
  • keyshidden: urządzenie ma dostępną klawiaturę sprzętową, ale jest ona ukryta i na urządzeniu nie jest włączona klawiatura programowa.
  • keyssoft: na urządzeniu jest włączona klawiatura programowa, niezależnie od tego, czy jest widoczna.

Jeśli podasz zasoby keysexposed, ale nie podasz zasobów keyssoft, system będzie używać zasobów keysexposed niezależnie od tego, czy klawiatura jest widoczna, o ile w systemie jest włączona klawiatura programowa.

Może się to zmienić w trakcie korzystania z aplikacji, jeśli użytkownik otworzy klawiaturę sprzętową. Więcej informacji o tym, jak wpływa to na aplikację w czasie działania, znajdziesz w artykule Obsługa zmian konfiguracji.

Zobacz też pola konfiguracji hardKeyboardHiddenkeyboardHidden, które wskazują odpowiednio widoczność klawiatury sprzętowej i widoczność dowolnego rodzaju klawiatury (w tym programowej).

Podstawowa metoda wprowadzania tekstu nokeys
qwerty
12key
  • nokeys: urządzenie nie ma klawiszy sprzętowych do wprowadzania tekstu.
  • qwerty: urządzenie ma klawiaturę sprzętową QWERTY, niezależnie od tego, czy jest ona widoczna dla użytkownika.
  • 12key: urządzenie ma 12-klawiszową klawiaturę sprzętową, niezależnie od tego, czy jest ona widoczna dla użytkownika.

Zobacz też pole konfiguracji keyboard, które wskazuje dostępną podstawową metodę wpisywania tekstu.

Wersja platformy (poziom interfejsu API) Przykłady:
v3
v4
v7
itd.

Poziom API obsługiwany przez urządzenie. Na przykład v1 w przypadku poziomu interfejsu API 1 (urządzenia z Androidem 1.0 lub nowszym) i v4 w przypadku poziomu interfejsu API 4 (urządzenia z Androidem 1.6 lub nowszym). Więcej informacji o tych wartościach znajdziesz w dokumencie Poziomy interfejsu Android API.

Uwaga: nie wszystkie wersje Androida obsługują wszystkie kwalifikatory. Użycie nowego kwalifikatora powoduje niejawne dodanie kwalifikatora wersji platformy, dzięki czemu starsze urządzenia mogą go ignorować. Na przykład użycie kwalifikatora w600dp automatycznie uwzględnia kwalifikator v13, ponieważ kwalifikator dostępnej szerokości został wprowadzony w interfejsie API na poziomie 13. Aby uniknąć problemów, zawsze uwzględniaj zestaw zasobów domyślnych (zestaw zasobów bez kwalifikatorów). Więcej informacji znajdziesz w sekcji Zapewnianie najlepszej zgodności urządzeń z zasobami.

Reguły nazw kwalifikatorów

Oto kilka zasad dotyczących używania nazw kwalifikatorów konfiguracji:

  • Możesz określić wiele kwalifikatorów dla jednego zestawu zasobów, oddzielając je myślnikami. Na przykład drawable-en-rUS-land dotyczy urządzeń w języku angielskim (Stany Zjednoczone) w orientacji poziomej.
  • Kwalifikatory muszą być podane w kolejności wymienionej w tabeli 2.
    • Nieprawidłowo: drawable-hdpi-port/
    • Poprawnie: drawable-port-hdpi/
  • Alternatywne katalogi zasobów nie mogą być zagnieżdżone. Nie możesz na przykład używać znaku res/drawable/drawable-en/.
  • W wartościach nie jest rozróżniana wielkość liter. Kompilator zasobów konwertuje nazwy katalogów na małe litery przed przetworzeniem, aby uniknąć problemów w systemach plików, w których wielkość liter nie ma znaczenia. Wielkie litery w nazwach służą tylko poprawie czytelności.
  • Obsługiwana jest tylko jedna wartość dla każdego typu kwalifikatora. Jeśli na przykład chcesz używać tych samych plików obiektów rysowalnych w Hiszpanii i Francji, nie możesz mieć katalogu o nazwie drawable-es-fr/. Zamiast tego potrzebujesz 2 katalogów zasobów, np. drawable-es/drawable-fr/, które zawierają odpowiednie pliki. Nie musisz jednak duplikować plików w obu lokalizacjach. Zamiast tego możesz utworzyć alias zasobu, jak opisano w sekcji Tworzenie zasobów aliasów.

Po zapisaniu alternatywnych zasobów w katalogach oznaczonych tymi kwalifikatorami Android automatycznie stosuje zasoby w aplikacji na podstawie bieżącej konfiguracji urządzenia. Za każdym razem, gdy zasób jest wymagany, Android sprawdza alternatywne katalogi zasobów, które zawierają żądany plik zasobu, a następnie znajduje najlepiej pasujący zasób.

Jeśli nie ma zasobów alternatywnych, które pasują do konkretnej konfiguracji urządzenia, Android używa odpowiednich zasobów domyślnych, czyli zestawu zasobów określonego typu, który nie zawiera kwalifikatora konfiguracji.

Tworzenie zasobów aliasów

Jeśli masz zasób, którego chcesz używać w przypadku więcej niż jednej konfiguracji urządzenia, ale nie chcesz udostępniać go jako zasobu domyślnego, nie musisz umieszczać tego samego zasobu w więcej niż jednym katalogu zasobów alternatywnych. Zamiast tego możesz utworzyć zasób alternatywny, który będzie działać jako alias zasobu zapisanego w domyślnym katalogu zasobów.

Uwaga: nie wszystkie zasoby oferują mechanizm, za pomocą którego można utworzyć alias do innego zasobu. W szczególności animacje, menu, zasoby surowe i inne nieokreślone zasoby w katalogu xml/ nie oferują tej funkcji.

Załóżmy na przykład, że masz ikonę aplikacji icon.png i potrzebujesz jej unikalnej wersji dla różnych regionów. Jednak 2 ustawienia regionalne, angielski – Kanada i francuski – Kanada, muszą korzystać z tej samej wersji. Nie musisz kopiować tego samego obrazu do katalogu zasobów zarówno w przypadku języka angielskiego (kanadyjskiego), jak i francuskiego (kanadyjskiego). Zamiast tego możesz zapisać obraz używany w obu przypadkach pod dowolną nazwą inną niż icon.png, np. icon_ca.png, i umieścić go w domyślnym katalogu res/drawable/. Następnie utwórz plik icon.xmlres/drawable-en-rCA/res/drawable-fr-rCA/, który odwołuje się do zasobu icon_ca.png za pomocą elementu <bitmap>. Dzięki temu możesz przechowywać tylko jedną wersję pliku PNG i 2 małe pliki XML, które do niej odsyłają. Szczegółowe informacje znajdziesz w przykładach w sekcjach poniżej.

Drawable

Aby utworzyć alias do istniejącego obiektu rysowalnego, użyj elementu <drawable>:

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

Jeśli zapiszesz ten plik jako icon.xml w alternatywnym katalogu zasobów, np. res/values-en-rCA/, zostanie on skompilowany do zasobu, do którego możesz się odwoływać jako R.drawable.icon, ale w rzeczywistości będzie to alias zasobu R.drawable.icon_ca, który jest zapisany w katalogu res/drawable/.

Układ

Aby utworzyć alias do istniejącego układu, użyj elementu <include>, który jest zawarty w elemencie <merge>:

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

Jeśli zapiszesz ten plik jako main.xml, zostanie on skompilowany w zasób, do którego możesz się odwoływać jako R.layout.main, ale w rzeczywistości jest to alias zasobu R.layout.main_ltr.

Ciągi znaków i inne proste wartości

Aby utworzyć alias do istniejącego ciągu znaków, użyj identyfikatora zasobu wybranego ciągu znaków jako wartości nowego ciągu znaków:

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

Zasób R.string.hi jest teraz aliasem zasobu R.string.hello.

Inne proste wartości działają w ten sam sposób, np. kolory:

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

Dostęp do zasobów aplikacji

Po udostępnieniu zasobu w aplikacji możesz go zastosować, odwołując się do jego identyfikatora. Wszystkie identyfikatory zasobów są zdefiniowane w klasie R projektu, którą narzędzie aapt generuje automatycznie.

Podczas kompilacji aplikacji aapt generuje klasę R, która zawiera identyfikatory zasobów dla wszystkich zasobów w katalogu res/. Dla każdego typu zasobu istnieje R podklasa, np. R.drawable dla wszystkich zasobów rysowalnych. Każdy zasób tego typu ma statyczną liczbę całkowitą, np. R.drawable.icon. Ta liczba całkowita to identyfikator zasobu, którego możesz użyć do pobrania zasobu.

Chociaż identyfikatory zasobów są określane w klasie R, nie musisz tam szukać, aby znaleźć identyfikator zasobu. Identyfikator zasobu zawsze składa się z tych elementów:

  • Typ zasobu: każdy zasób jest pogrupowany według „typu”, np. string, drawablelayout. Więcej informacji o różnych typach znajdziesz w tym artykule.
  • Nazwa zasobu, czyli nazwa pliku bez rozszerzenia lub wartość atrybutu android:name w pliku XML, jeśli zasób jest prostą wartością, np. ciągiem znaków.

Dostęp do zasobu możesz uzyskać na 2 sposoby:

  • W kodzie: używając statycznej liczby całkowitej z podklasy klasy R, na przykład:
    R.string.hello

    string to typ zasobu, a hello to nazwa zasobu. Istnieje wiele interfejsów API Androida, które mogą uzyskać dostęp do Twoich zasobów, gdy podasz identyfikator zasobu w tym formacie. Więcej informacji znajdziesz w sekcji Dostęp do zasobów w kodzie.

  • W XML: za pomocą specjalnej składni XML, która odpowiada identyfikatorowi zasobu zdefiniowanemu w klasie R, np.:
    @string/hello

    string to typ zasobu, a hello to nazwa zasobu. Możesz użyć tej składni w zasobie XML w dowolnym miejscu, w którym oczekiwana jest wartość podana w zasobie. Więcej informacji znajdziesz w sekcji Dostęp do zasobów z pliku XML.

Dostęp do zasobów w kodzie

Aby użyć zasobu w kodzie, przekaż identyfikator zasobu jako parametr metody. Możesz na przykład ustawić ImageView, aby używać zasobu res/drawable/myimage.png za pomocą 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);

Możesz też pobierać poszczególne zasoby za pomocą metod w Resources, których instancję możesz uzyskać za pomocą getResources().

Składnia

Oto składnia odwołania się do zasobu w kodzie:

[<package_name>.]R.<resource_type>.<resource_name>
  • <package_name> to nazwa pakietu, w którym znajduje się zasób (nie jest wymagana w przypadku odwoływania się do zasobów z własnego pakietu).
  • <resource_type> to podklasa R dla typu zasobu.
  • <resource_name> to nazwa pliku zasobu bez rozszerzenia lub wartość atrybutu android:name w elemencie XML w przypadku prostych wartości.

Więcej informacji o poszczególnych typach zasobów i sposobach odwoływania się do nich znajdziesz w artykule Omówienie typów zasobów.

Przypadki użycia

Istnieje wiele metod, które akceptują parametr identyfikatora zasobu. Zasoby możesz pobierać za pomocą metod w Resources. Instancję Resources możesz uzyskać za pomocą Context.getResources().

Oto kilka przykładów dostępu do zasobów w kodzie:

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);

Ostrzeżenie: nie modyfikuj ręcznie pliku R.java. Jest on generowany przez narzędzie aapt podczas kompilacji projektu. Wszelkie zmiany zostaną zastąpione przy następnej kompilacji.

Dostęp do zasobów z pliku XML

Wartości niektórych atrybutów i elementów XML możesz zdefiniować za pomocą odwołania do istniejącego zasobu. Często robisz to podczas tworzenia plików układu, aby dostarczać ciągi znaków i obrazy do widżetów.

Jeśli na przykład dodasz do układu element Button, użyj zasobu ciągu w przypadku tekstu przycisku:

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

Składnia

Oto składnia odwołania do zasobu w zasobie XML:

@[<package_name>:]<resource_type>/<resource_name>
  • <package_name> to nazwa pakietu, w którym znajduje się zasób (nie jest wymagana, gdy odwołujesz się do zasobów z tego samego pakietu).
  • <resource_type> to podklasa R dla typu zasobu.
  • <resource_name> to nazwa pliku zasobu bez rozszerzenia lub wartość atrybutu android:name w elemencie XML w przypadku prostych wartości.

Więcej informacji o poszczególnych typach zasobów i sposobach odwoływania się do nich znajdziesz w artykule Omówienie typów zasobów.

Przypadki użycia

W niektórych przypadkach musisz użyć zasobu jako wartości w pliku XML, np. aby zastosować obiekt rysowalny do widżetu, ale możesz też użyć zasobu w pliku XML w dowolnym miejscu, w którym akceptowana jest prosta wartość. Jeśli na przykład masz ten plik zasobów, który zawiera zasób koloruzasób tekstowy:

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

W tym pliku układu możesz użyć tych zasobów, aby ustawić kolor tekstu i ciąg tekstowy:

<?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" />

W tym przypadku nie musisz podawać nazwy pakietu w odwołaniu do zasobu, ponieważ zasoby pochodzą z Twojego pakietu. Aby odwołać się do zasobu systemowego, musisz podać nazwę pakietu, jak pokazano w tym przykładzie:

<?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" />

Uwaga: zawsze używaj zasobów ciągów znaków, aby aplikacja mogła być zlokalizowana w innych językach. Informacje o tworzeniu zasobów alternatywnych (np. zlokalizowanych ciągów tekstowych) znajdziesz w artykule Dostarczanie zasobów alternatywnych. Pełny przewodnik po lokalizowaniu aplikacji na inne języki znajdziesz w artykule Lokalizowanie aplikacji.

Do tworzenia aliasów możesz też używać zasobów w formacie XML. Możesz na przykład utworzyć obiekt rysowalny, który jest aliasem innego obiektu rysowalnego:

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

Może się to wydawać zbędne, ale może być bardzo przydatne w przypadku korzystania z zasobu alternatywnego. Więcej informacji znajdziesz w sekcji dotyczącej tworzenia zasobów aliasów.

Atrybuty stylu referencyjnego

Zasób atrybutu stylu umożliwia odwoływanie się do wartości atrybutu w obecnie stosowanym motywie. Odwoływanie się do atrybutu stylu umożliwia dostosowywanie wyglądu elementów interfejsu przez nadawanie im stylu zgodnego ze standardowymi odmianami dostarczanymi przez bieżący motyw zamiast podawania zakodowanej na stałe wartości. Odwołanie do atrybutu stylu oznacza w zasadzie: „Użyj stylu zdefiniowanego przez ten atrybut w bieżącym motywie”.

Składnia nazwy odwołującej się do atrybutu stylu jest niemal identyczna ze zwykłym formatem zasobu, ale zamiast symbolu „at” (@) użyj znaku zapytania (?). Część dotycząca typu zasobu jest opcjonalna. Składnia odwołania wygląda więc tak:

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

Na przykład tak możesz odwołać się do atrybutu, aby ustawić kolor tekstu zgodny z kolorem tekstu dodatkowego motywu systemowego:

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

W tym przypadku atrybut android:textColor określa nazwę atrybutu stylu w bieżącym motywie. Android używa teraz wartości zastosowanej do atrybutu android:textColorSecondary jako wartości atrybutu android:textColor w tym widżecie. Narzędzie zasobów systemowych wie, że w tym kontekście oczekiwany jest zasób atrybutu, więc nie musisz podawać jego typu, czyli ?android:attr/textColorSecondary. Możesz wykluczyć typ attr.

Dostęp do oryginalnych plików

Chociaż jest to rzadkie, możesz potrzebować dostępu do oryginalnych plików i katalogów. Jeśli tak jest, zapisywanie plików w res/ nie będzie działać, ponieważ zasób z res/ można odczytać tylko za pomocą identyfikatora zasobu. Zamiast tego możesz zapisać zasoby w katalogu assets/.

Pliki zapisane w katalogu assets/ nie mają identyfikatora zasobu, więc nie możesz się do nich odwoływać za pomocą klasy R ani z zasobów XML. Zamiast tego możesz wysyłać zapytania dotyczące plików w katalogu assets/ jak w przypadku zwykłego systemu plików i odczytywać surowe dane za pomocą AssetManager.

Jeśli jednak potrzebujesz tylko możliwości odczytywania nieprzetworzonych danych (np. pliku wideo lub pliku audio), zapisz plik w katalogu res/raw/ i odczytaj strumień bajtów za pomocą openRawResource().

Dostęp do zasobów platformy

Android zawiera wiele standardowych zasobów, takich jak style, motywy i układy. Aby uzyskać dostęp do tych zasobów, podaj w odwołaniu do zasobu android nazwę pakietu. Na przykład Android udostępnia zasób layoutu, którego możesz użyć w przypadku elementów listy w 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));

W tym przykładzie simple_list_item_1 to zasób layoutu zdefiniowany przez platformę dla elementów w ListView. Możesz użyć tego widoku zamiast tworzyć własny układ elementów listy.

Zapewnianie najlepszej zgodności urządzeń z zasobami

Aby aplikacja obsługiwała wiele konfiguracji urządzeń, bardzo ważne jest, aby zawsze udostępniać domyślne zasoby dla każdego typu zasobu używanego przez aplikację.

Jeśli na przykład Twoja aplikacja obsługuje kilka języków, zawsze uwzględniaj katalog values/ (w którym zapisane są ciągi znaków) bez kwalifikatora języka i regionu. Jeśli umieścisz wszystkie pliki ciągów znaków w katalogach z kwalifikatorem języka i regionu, aplikacja ulegnie awarii, gdy zostanie uruchomiona na urządzeniu, na którym ustawiono język nieobsługiwany przez ciągi znaków.

Jeśli udostępnisz zasoby domyślnevalues/, aplikacja będzie działać prawidłowo, nawet jeśli użytkownik nie rozumie języka, w którym jest wyświetlana. To lepsze niż awaria.

Podobnie, jeśli udostępniasz różne zasoby układu w zależności od orientacji ekranu, wybierz jedną orientację jako domyślną. Na przykład zamiast udostępniać zasoby układu w layout-land/ dla orientacji poziomej i layout-port/ dla orientacji pionowej, pozostaw jeden jako domyślny, np. layout/ dla orientacji poziomej i layout-port/ dla orientacji pionowej.

Dostarczanie zasobów domyślnych jest ważne nie tylko dlatego, że aplikacja może działać w nieprzewidzianej konfiguracji, ale też dlatego, że nowe wersje Androida czasami dodają kwalifikatory konfiguracji, których starsze wersje nie obsługują. Jeśli używasz nowego kwalifikatora zasobów, ale zachowujesz zgodność kodu ze starszymi wersjami Androida, to gdy starsza wersja Androida uruchomi Twoją aplikację, ulegnie ona awarii, jeśli nie udostępnisz zasobów domyślnych, ponieważ nie będzie mogła używać zasobów nazwanych z użyciem nowego kwalifikatora.

Jeśli na przykład wartość minSdkVersion wynosi 4, a wszystkie zasoby rysowalne kwalifikujesz za pomocą trybu nocnego (night lub notnight, które zostały dodane w interfejsie API na poziomie 8), urządzenie z interfejsem API na poziomie 4 nie będzie mieć dostępu do zasobów rysowalnych i ulegnie awarii. W tym przypadku prawdopodobnie chcesz, aby domyślnymi zasobami były zasoby notnight, więc wyklucz ten kwalifikator i umieść zasoby rysowalne w folderze drawable/ lub drawable-night/.

Krótko mówiąc, aby zapewnić jak najlepszą zgodność z urządzeniami, zawsze udostępniaj domyślne zasoby, których aplikacja potrzebuje do prawidłowego działania. Następnie utwórz alternatywne zasoby dla konkretnych konfiguracji urządzeń, używając kwalifikatorów konfiguracji.

Istnieje jeden wyjątek od tej reguły: jeśli minSdkVersion aplikacji ma wartość 4 lub większą, nie musisz używać domyślnych zasobów rysowalnych, gdy udostępniasz alternatywne zasoby rysowalne z kwalifikatorem gęstości ekranu. Nawet bez domyślnych zasobów rysowalnych Android może znaleźć najlepsze dopasowanie wśród alternatywnych gęstości ekranu i w razie potrzeby skalować mapy bitowe. Aby jednak zapewnić jak najlepsze wrażenia na wszystkich typach urządzeń, podaj alternatywne elementy rysunkowe dla wszystkich 3 rodzajów gęstości.

Jak Android znajduje najlepiej pasujący zasób

Gdy zażądasz zasobu, dla którego podasz alternatywy, Android wybierze w czasie działania, którego zasobu alternatywnego użyć, w zależności od bieżącej konfiguracji urządzenia. Aby pokazać, jak Android wybiera zasób alternatywny, załóżmy, że te katalogi zasobów rysowalnych zawierają różne wersje tych samych obrazów:

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

Załóżmy, że konfiguracja urządzenia jest taka:

Locale = en-GB
Orientacja ekranu = port
Gęstość pikseli na ekranie = hdpi
Typ ekranu dotykowego = notouch
Podstawowa metoda wprowadzania tekstu = 12key

Porównując konfigurację urządzenia z dostępnymi zasobami alternatywnymi, Android wybiera elementy rysunkowe z drawable-en-port.

System podejmuje decyzję o tym, z których zasobów skorzystać, na podstawie tej logiki:

Rysunek 2. Schemat blokowy pokazujący, jak Android znajduje najlepiej dopasowany zasób.

  1. Usuń pliki zasobów, które są sprzeczne z konfiguracją urządzenia.

    Katalog drawable-fr-rCA/ został usunięty, ponieważ jest sprzeczny z ustawieniami regionalnymi en-GB.

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

    Wyjątek: gęstość pikseli na ekranie to jedyny kwalifikator, który nie jest eliminowany z powodu sprzeczności. Mimo że gęstość ekranu urządzenia to hdpi, element drawable-port-ldpi/ nie jest usuwany, ponieważ na tym etapie każda gęstość ekranu jest uznawana za pasującą. Więcej informacji znajdziesz w artykule Omówienie zgodności z ekranem.

  2. Znajdź na liście kolejny kwalifikator o najwyższym priorytecie (tabela 2). (Zacznij od kodu kategorii sprzedawcy).
  3. Czy któryś z katalogów zasobów zawiera ten kwalifikator?
    • Jeśli nie, wróć do kroku 2 i sprawdź kolejny kwalifikator. W tym przykładzie odpowiedź to „nie”, dopóki nie zostanie osiągnięty kwalifikator języka.
    • Jeśli tak, przejdź do kroku 4.
  4. Usuń katalogi zasobów, które nie zawierają tego kwalifikatora. W tym przykładzie system eliminuje wszystkie katalogi, które nie zawierają kwalifikatora języka:
    drawable/
    drawable-en/
    drawable-en-port/
    drawable-en-notouch-12key/
    drawable-port-ldpi/
    drawable-port-notouch-12key/
    

    Wyjątek: jeśli kwalifikator dotyczy gęstości pikseli na ekranie, Android wybiera opcję, która najbardziej odpowiada gęstości pikseli na ekranie urządzenia. Ogólnie rzecz biorąc, Android woli zmniejszać większy obraz oryginalny niż powiększać mniejszy obraz oryginalny. Więcej informacji znajdziesz w omówieniu zgodności ekranów.

  5. Powtarzaj kroki 2, 3 i 4, aż pozostanie tylko jeden katalog. W tym przykładzie następnym kwalifikatorem, dla którego istnieją dopasowania, jest screen orientation. Zatem zasoby, które nie określają orientacji ekranu, są eliminowane:
    drawable-en/
    drawable-en-port/
    drawable-en-notouch-12key/
    

    Pozostały katalog to drawable-en-port.

Chociaż ta procedura jest wykonywana w przypadku każdego żądanego zasobu, system optymalizuje niektóre jej aspekty. Jedną z takich optymalizacji jest to, że gdy znana jest konfiguracja urządzenia, można wyeliminować alternatywne zasoby, które nigdy nie będą pasować. Jeśli na przykład język konfiguracji to angielski, żaden katalog zasobów z kwalifikatorem języka ustawionym na inny język niż angielski nie jest uwzględniany w puli sprawdzanych zasobów (ale katalog zasobów bez kwalifikatora języka jest nadal uwzględniany).

Podczas wybierania zasobów na podstawie kwalifikatorów rozmiaru ekranu system używa zasobów przeznaczonych na ekran mniejszy niż bieżący, jeśli nie ma zasobów, które lepiej pasują. Na przykład w razie potrzeby ekran o dużym rozmiarze korzysta z zasobów ekranu o normalnym rozmiarze.

Jeśli jednak jedyne dostępne zasoby są większe niż bieżący ekran, system nie ich używa, a aplikacja ulega awarii, jeśli żadne inne zasoby nie pasują do konfiguracji urządzenia. Dzieje się tak na przykład, gdy wszystkie zasoby układu są oznaczone kwalifikatorem xlarge, ale urządzenie ma ekran o normalnym rozmiarze.

Uwaga: pierwszeństwo kwalifikatora (w tabeli 2) jest ważniejsze niż liczba kwalifikatorów, które dokładnie pasują do urządzenia. W przykładzie powyżej w kroku 4 ostatni wybór na liście zawiera 3 kwalifikatory, które dokładnie pasują do urządzenia (orientacja, typ ekranu dotykowego i metoda wprowadzania), a drawable-en ma tylko 1 parametr, który pasuje (język). Język ma jednak wyższy priorytet niż te inne kwalifikatory, więcdrawable-port-notouch-12key jest eliminowany.