Pojęcia i implementacja w Jetpack Compose
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 określonych 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 wygenerowanych w klasie R w projekcie. Z tego dokumentu dowiesz się, jak grupować zasoby w projekcie aplikacji na Androida. Wyjaśniamy też, jak udostępniać alternatywne zasoby dla konkretnych konfiguracji urządzeń, a potem 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.
Tabela 1. Katalogi zasobów są obsługiwane w katalogu projektu res/.
Katalog |
Typ zasobu |
|
|
Pliki XML, które definiują animacje właściwości. |
|
|
Pliki XML, które definiują animacje Tween. Animacje właściwości można też zapisywać w tym katalogu, ale w przypadku animacji właściwości zalecany jest katalog |
|
|
Pliki XML, które definiują listę kolorów stanu. Więcej informacji znajdziesz w artykule Lista stanów kolorów. |
|
|
Pliki bitmapowe (PNG, .
Więcej informacji znajdziesz w artykule Zasoby rysowalne. |
|
|
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 |
|
|
Pliki XML, które definiują układ interfejsu użytkownika. Więcej informacji znajdziesz w artykule Zasób układu. |
|
|
Pliki XML, które definiują menu aplikacji, np. menu opcji, menu kontekstowe lub podmenu. Więcej informacji znajdziesz w artykule Zasób menu. |
|
|
dowolne pliki, które mają być zapisane w formie nieprzetworzonej; Aby otworzyć te zasoby za pomocą surowego Jeśli jednak potrzebujesz dostępu do oryginalnych nazw plików i hierarchii plików, rozważ zapisanie zasobów w katalogu |
|
|
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 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. Jednak w celu uniknięcia wątpliwości możesz umieścić unikalne typy zasobów w różnych plikach. Oto kilka przykładów konwencji nazw plików w przypadku zasobów, które możesz utworzyć w tym katalogu:
Więcej informacji znajdziesz w sekcjach Zasoby tekstowe, Zasoby stylu i Więcej typów zasobów. |
|
|
Dowolne pliki XML, które można odczytać w czasie działania programu, wywołując funkcję |
|
|
Pliki czcionek z rozszerzeniami TTF, OTF lub TTC albo pliki XML zawierające element |
Zasoby zapisane w podkatalogach zdefiniowanych w tabeli 1 są zasobami domyślnymi. Oznacza to, że zasoby te określają domyślny wygląd i treść 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ń. Możesz na przykład dodać alternatywne zasoby rysowalne dla różnych gęstości ekranu i alternatywne zasoby tekstowe 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, wykonaj te czynności:
Utwórz w folderze
res/nowy katalog o nazwie w formacie<resources_name>-<qualifier>.<resources_name>to nazwa katalogu odpowiednich zasobów domyślnych (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ż jedną właściwość
<qualifier>. Rozdzielaj je myślnikami.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łady domyślnych i alternatywnych zasobów:
res/
drawable/
icon.png
background.png
drawable-hdpi/
icon.png
background.png
Kwalifikator hdpi oznacza, że zasoby w tym katalogu są przeznaczone na urządzenia z ekranem o wysokiej gęstości pikseli. Obrazy w tych katalogach zasobów są dostosowane do konkretnych 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.
W tabeli 2 podano prawidłowe kwalifikatory konfiguracji w kolejności ich ważności. Do jednej nazwy katalogu możesz dodać kilka kwalifikatorów, rozdzielając je myślnikami. Jeśli używasz wielu kwalifikatorów dla 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:
|
Kod kraju (MCC), opcjonalnie z kodem MNC z karty SIM w urządzeniu. Na przykład 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 |
Język, pismo (opcjonalnie) i region (opcjonalnie) |
Przykłady:
|
Język jest określany przez dwuliterowy kod języka ISO 639-2{:.external}, opcjonalnie po którym następuje dwuliterowy kod regionu ISO 3166-1-alpha-2{:.external} (poprzedzony małą literą W kodach nie jest rozróżniana wielkość liter. Prefiks W Androidzie 7.0 (poziom interfejsu API 24) wprowadzono obsługę tagów języka zgodnych ze standardem BCP 47{:.external}, 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 Tags for Identifying Languages{:.external}. Aby użyć tagu języka BCP 47, połącz znak 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ę |
| Rodzaj gramatyczny | masculinefeminineneuter |
Płeć gramatyczna użytkownika. Używane w przypadku języków, w których występuje rodzaj gramatyczny. Jeśli na przykład musisz udostępnić różne zasoby użytkownikom posługującym się językiem francuskim, możesz użyć katalogów takich jak te:
Zobacz: Rodzaj gramatyczny w Androidzie. Zobacz też metodę konfiguracji Dodano na poziomie API 34. |
Kierunek układu |
|
Kierunek układu aplikacji. 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 każdego innego języka zapisanego od prawej do lewej, takiego jak perski czy hebrajski, użyj katalogów w tym formacie:
Uwaga: aby włączyć w aplikacji funkcje układu od prawej do lewej, musisz ustawić wartość Dodano na poziomie API 17. |
Najmniejsza szerokość |
Przykłady:
itd. |
Najkrótszy wymiar obszaru ekranu dostępnego dla aplikacji. W przypadku okna aplikacji jest to krótszy z dostępnych wymiarów wysokości i szerokości okna. 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 layoutu w katalogu 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ść sztywne 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, jaka jest najmniejsza możliwa 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 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:
Jeśli aplikacja udostępnia wiele katalogów zasobów z różnymi wartościami kwalifikatora Dodano na poziomie 13 interfejsu API. Zobacz też atrybut 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ść |
Przykłady:
itd. |
Określa minimalną dostępną szerokość lub wysokość ekranu (w 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. Dzięki temu możesz ich używać do określania minimalnej szerokości lub wysokości wymaganej w przypadku układu zamiast używać jednocześnie kwalifikatorów rozmiaru i orientacji ekranu. Jeśli aplikacja udostępnia wiele katalogów zasobów z różnymi wartościami tych konfiguracji, system używa tego, który jest najbliższy (ale nie przekracza) 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 na krawędziach 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ą 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 np. rzeczywisty ekran ma szerokość 720 dp i wysokość 1280 dp, a jeden zasób jest oznaczony jako w720dp, a drugi jako w700dp-h1200dp, ten drugi zostanie wybrany, mimo że pierwszy jest dokładnym dopasowaniem do tego, co określa. Dodano na poziomie 13 interfejsu API. Zobacz też pola konfiguracji 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 |
|
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ć zasobów, które są najlepiej dopasowane. Uwaga: jeśli wszystkie zasoby używają kwalifikatora rozmiaru, który jest większy niż bieżący ekran, system ich nie używa, a aplikacja ulega awarii w czasie działania. Dzieje się tak na przykład, gdy wszystkie zasoby układu są oznaczone kwalifikatorem Dodano na poziomie API 4. Zobacz też pole konfiguracji Więcej informacji znajdziesz w omówieniu zgodności ekranów. |
Format ekranu |
|
Dodano na poziomie API 4. Zależy to wyłącznie od współczynnika proporcji ekranu (ekran Zobacz też pole konfiguracji |
Okrągły ekran |
|
Dodano na poziomie interfejsu API 23. Sprawdź też metodę konfiguracji |
Szeroka gama kolorów |
|
Dodano na poziomie interfejsu API 26. Sprawdź też metodę konfiguracji |
High Dynamic Range (HDR) |
|
Dodano na poziomie interfejsu API 26. Zobacz też metodę konfiguracji |
Orientacja ekranu |
|
Może się to zmienić w trakcie korzystania z aplikacji, jeśli użytkownik obróci ekran. Więcej informacji o tym, jak to wpływa na aplikację w czasie działania, znajdziesz w artykule Obsługa zmian konfiguracji. Zobacz też pole konfiguracji |
Tryb interfejsu |
|
Dodano na poziomie API 8; telewizor dodano na poziomie API 13; urządzenie dodano na poziomie API 16; zegarek dodano na poziomie API 20; zestaw VR dodano na poziomie API 26. 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ą ikony |
Tryb nocny |
|
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 takim przypadku tryb zmienia się w zależności od pory dnia. Ten tryb możesz włączyć lub wyłączyć za pomocą |
Gęstość pikseli ekranu (dpi) |
|
Między 6 głównymi gęstościami (z pominięciem 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 zasobów alternatywnych 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 omówieniu zgodności z ekranem. |
Typ ekranu dotykowego |
|
Zobacz też pole konfiguracji |
Dostępność klawiatury |
|
Jeśli podasz zasoby Może się to zmienić w trakcie korzystania z aplikacji, jeśli użytkownik otworzy klawiaturę sprzętową. Więcej informacji o tym, jak to wpływa na aplikację w czasie działania, znajdziesz w artykule Obsługa zmian konfiguracji. Zobacz też pola konfiguracji |
Podstawowa metoda wprowadzania tekstu |
|
Zobacz też pole konfiguracji |
Dostępność klawiszy nawigacyjnych |
|
Może się to zmienić w trakcie korzystania z aplikacji, jeśli użytkownik wyświetli klawisze nawigacyjne. Więcej informacji o tym, jak to wpływa na aplikację w czasie działania, znajdziesz w artykule Obsługa zmian konfiguracji. Zobacz też pole konfiguracji |
Podstawowa metoda nawigacji bezdotykowej |
|
Zobacz też pole konfiguracji |
Wersja platformy (poziom interfejsu API) |
Przykłady:
itd. |
Poziom API obsługiwany przez urządzenie. Na przykład |
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 reguła
drawable-en-rUS-landma zastosowanie do urządzeń w języku angielskim (USA) w orientacji poziomej. - Kwalifikatory muszą być podane w kolejności wymienionej w tabeli 2.
- Nieprawidłowo:
drawable-hdpi-port/ - Prawidłowo:
drawable-port-hdpi/
- Nieprawidłowo:
- Alternatywne katalogi zasobów nie mogą być zagnieżdżone. Na przykład nie możesz mieć
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/idrawable-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, czy istnieją alternatywne katalogi zasobów zawierające żądany plik zasobu, a następnie znajduje najlepiej pasujący zasób.
Jeśli nie ma zasobów alternatywnych, które pasują do określonej konfiguracji urządzenia, Android używa odpowiednich zasobów domyślnych – 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 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.
Załóżmy, ż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ą używać tej samej wersji. Nie musisz kopiować tego samego obrazu do katalogu zasobów zarówno w przypadku języka angielskiego w Kanadzie, jak i francuskiego w Kanadzie.
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.xml w res/drawable-en-rCA/ i 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 1 wersję pliku PNG i 2 małe pliki XML, które do niego 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 jest to alias zasobu R.drawable.icon_ca, który jest zapisany w 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.
Dostęp do zasobów aplikacji
Po podaniu 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 podklasa R, 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 zgrupowany w „typ”, np.
string, drawableilayout. Więcej informacji o różnych typach znajdziesz w przeglądzie typów zasobów. - Nazwa zasobu, czyli nazwa pliku bez rozszerzenia lub wartość atrybutu
android:namew pliku XML, jeśli zasób jest prostą wartością, np. ciągiem.
Dostęp do zasobu możesz uzyskać na 2 sposoby:
- W kodzie: używając statycznej liczby całkowitej z podklasy klasy
R, np.:R.string.hellostringto typ zasobu, ahelloto 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
Rklasie, np.:@string/hellostringto typ zasobu, ahelloto 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 poziomu kodu 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ływania 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, gdy odwołujesz się do zasobów z własnego pakietu).<resource_type>to podklasaRdla typu zasobu.<resource_name>to nazwa pliku zasobu bez rozszerzenia lub wartość atrybutuandroid:namew elemencie XML w przypadku prostych wartości.
Przypadki użycia
Istnieje wiele metod, które akceptują parametr identyfikatora zasobu. Zasoby można 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);
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 tekstowe i obrazy do widżetów.
Jeśli na przykład dodasz do układu Button, użyj zasobu w postaci ciągu znaków dla 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 podklasaRdla typu zasobu.<resource_name>to nazwa pliku zasobu bez rozszerzenia lub wartość atrybutuandroid:namew elemencie XML w przypadku prostych wartości.
Przypadki użycia
W niektórych przypadkach musisz użyć zasobu jako wartości w XML, np. aby zastosować obiekt rysowalny do widżetu, ale możesz też użyć zasobu w XML w dowolnym miejscu, które akceptuje prostą wartość. Załóżmy, że masz ten plik zasobów, który zawiera zasób koloru i zasó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" />
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 aktualnie stosowanym motywie. Odwołanie się do atrybutu stylu umożliwia dostosowanie wyglądu elementów interfejsu przez nadanie im stylu zgodnego ze standardowymi odmianami dostarczanymi przez bieżący motyw zamiast podawania zakodowanej na stałe wartości. Odwoływanie się do atrybutu stylu oznacza w zasadzie: „Użyj stylu zdefiniowanego przez ten atrybut w bieżącym motywie”.
Składnia nazwy atrybutu stylu jest niemal identyczna ze składnią zwykłego formatu zasobu, ale zamiast symbolu „at” (@) użyj znaku zapytania (?). Część dotycząca typu zasobu jest opcjonalna. Składnia odwołania jest następująca:
?[<package_name>:][<resource_type>/]<resource_name>
Możesz na przykład odwołać się do atrybutu, aby ustawić kolor tekstu tak, aby pasował do koloru 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 stylu 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że się zdarzyć, że będziesz 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ż jedynym sposobem odczytania zasobu z res/ jest użycie 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 do plików w katalogu assets/ jak do 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ą funkcji 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, zakwalifikuj odwołanie do zasobu za pomocą android nazwy pakietu. Na przykład Android udostępnia zasób layoutu, którego możesz używać 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 układu 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 w katalogach, które mają kwalifikator języka i regionu, aplikacja ulegnie awarii, gdy zostanie uruchomiona na urządzeniu ustawionym na język, którego ciągi nie obsługują.
Jeśli udostępnisz domyślne zasoby values/, 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 folderze layout-land/ dla orientacji poziomej i w folderze 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, aplikacja uruchomiona na starszej wersji Androida ulegnie awarii, jeśli nie udostępnisz zasobów domyślnych, ponieważ nie będzie mogła używać zasobów nazwanych za pomocą 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 na poziomie API 8), urządzenie z poziomem API 4 nie będzie miało dostępu do zasobów rysowalnych i ulegnie awarii. W takim przypadku prawdopodobnie chcesz, aby notnight były domyślnymi zasobami, 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 Twojej aplikacji wynosi co najmniej 4, nie musisz podawać domyślnych zasobów rysowalnych, gdy udostępniasz alternatywne zasoby rysowalne z kwalifikatorem gęstości ekranu. Nawet bez domyślnych obiektów rysowalnych Android może znaleźć najlepsze dopasowanie wśród alternatywnych gęstości ekranu i w razie potrzeby skalować bitmapy. Aby jednak zapewnić najlepsze wrażenia na wszystkich typach urządzeń, udostępnij alternatywne elementy rysunkowe dla wszystkich 3 rodzajów gęstości.