Zasoby to dodatkowe pliki i treści statyczne używane w kodzie, np. mapy bitowe, definicje układu, ciągi znaków interfejsu użytkownika, instrukcje animacji itp.
Zawsze udostępniaj na zewnątrz zasoby aplikacji, takie jak obrazy czy ciągi znaków z kodu, aby móc je utrzymywać niezależnie. Udostępnij też zasoby alternatywne dla konkretnych konfiguracji urządzeń, grupując je w specjalnie nazywanych katalogach zasobów. W czasie działania Android używa odpowiedniego zasobu na podstawie bieżącej konfiguracji. Możesz na przykład określić różne układy interfejsu w zależności od rozmiaru ekranu lub różne ciągi znaków w zależności od ustawień językowych.
Gdy udostępnisz zasoby aplikacji na zewnątrz, możesz uzyskać do nich dostęp za pomocą identyfikatorów zasobów generowanych w klasie R
projektu.
W tym dokumencie opisujemy, jak grupować zasoby w projekcie Androida. Pokazuje też, jak udostępnić alternatywne zasoby na potrzeby konkretnych konfiguracji urządzeń, a następnie uzyskać do nich dostęp z poziomu kodu aplikacji lub innych plików XML.
Typy zasobów grupy
Umieść każdy typ zasobów w określonym podkatalogu katalogu res/
projektu. Na przykład oto hierarchia plików prostego projektu:
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 jego podkatalogach: zasób graficzny, dwa zasoby układu, katalog mipmap/
dla ikon programu uruchamiającego oraz plik zasobów w postaci ciągu znaków. Nazwy katalogów zasobów są ważne i zostały opisane w tabeli 1.
Uwaga: więcej informacji na temat korzystania z folderów mipmap znajdziesz w artykule na temat umieszczania ikon aplikacji w katalogach mipmap.
Katalog | Typ zasobu |
---|---|
animator/ |
Pliki XML definiujące animacje właściwości. |
anim/ |
Pliki XML definiujące Tweenanimations. W tym katalogu można też zapisywać animacje właściwości, ale w przypadku animacji właściwości preferowany jest katalog animator/ , który pozwala odróżnić te 2 typy. |
color/ |
Pliki XML definiujące listę stanów kolorów. Więcej informacji znajdziesz w sekcji Zasób listy stanów kolorów. |
drawable/ |
Pliki bitmapy (PNG,
Więcej informacji znajdziesz w artykule Materiały rysowalne. |
mipmap/ |
Pliki rysowalne dla różnych gęstości ikon programu uruchamiającego. Więcej informacji o zarządzaniu ikonami programu uruchamiającego w folderach mipmap/ znajdziesz w artykule o umieszczaniu ikon aplikacji w katalogach mipmap. |
layout/ |
Pliki XML, które definiują układ interfejsu użytkownika. Więcej informacji znajdziesz w artykule Zasób Układ. |
menu/ |
Pliki XML, które definiują menu aplikacji, takie jak menu opcji, menu kontekstowe lub menu podrzędne. Więcej informacji znajdziesz w sekcji Zasób menu. |
raw/ |
Dowolnych plików do zapisania w nieprzetworzonej postaci. Aby otworzyć te zasoby za pomocą nieprzetworzonego zasobu Jeśli jednak potrzebujesz dostępu do oryginalnych nazw plików i hierarchii plików, rozważ zapisanie zasobów w katalogu |
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 Ponieważ każdy zasób jest definiowany przez własny element XML, możesz nadać plikowi dowolną nazwę, a różne typy zasobów umieścić w jednym pliku. Warto jednak umieścić unikalne typy zasobów w różnych plikach. Oto przykładowe konwencje nazw plików zasobów, które można utworzyć w tym katalogu:
Więcej informacji znajdziesz w sekcjach Zasoby tekstowe, Zasób stylu i Więcej typów zasobów. |
xml/ |
Dowolne pliki XML, które można odczytać w czasie działania, wywołując Resources.getXML() . W tym miejscu trzeba zapisać różne pliki konfiguracji XML, np. konfigurację wyszukiwania. |
font/ |
Pliki czcionek z rozszerzeniami takimi jak TTF, OTF lub TTC albo pliki XML, które zawierają element <font-family> . Więcej informacji o czcionkach jako zasobach znajdziesz w artykule o dodawaniu 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 artykule Omówienie typów zasobów.
Zasoby zapisywane w podkatalogach zdefiniowanych w tabeli 1 są zasobami domyślnymi. Oznacza to, że określają one domyślny wygląd i zawartość 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 tekstowe, które tłumaczą tekst w interfejsie w zależności od ustawienia języka na urządzeniu. Aby zapewnić różne zasoby na potrzeby różnych konfiguracji urządzeń, oprócz zasobów domyślnych musisz podać też zasoby alternatywne.
Udostępnianie alternatywnych zasobów
Większość aplikacji udostępnia alternatywne zasoby do obsługi określonych konfiguracji urządzeń. Na przykład możesz uwzględnić alternatywne, możliwe do rysowania zasoby o różnej 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 aplikacji.
Aby określić alternatywy specyficzne dla konfiguracji dla zbioru zasobów, wykonaj te czynności:
- W usłudze
res/
utwórz 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 pojedynczą konfigurację, w której mają być używane te zasoby (zdefiniowaną w tabeli 2).
Możesz dołączyć więcej niż 1 element
<qualifier>
. Oddziel je łącznikiem.Uwaga: gdy dodajesz wiele kwalifikatorów, musisz je umieścić w tej samej kolejności co w tabeli 2. Jeśli kwalifikatory są ułożone w nieprawidłowej kolejności, zasoby są ignorowane.
- Zapisz odpowiednie zasoby alternatywne w tym nowym katalogu. Pliki zasobów muszą mieć taką samą nazwę jak domyślne pliki zasobów.
Oto na przykład zasoby domyślne i alternatywne:
res/ drawable/ icon.png background.png drawable-hdpi/ icon.png background.png
Kwalifikator hdpi
wskazuje, że zasoby w tym katalogu są przeznaczone dla urządzeń z ekranem o dużej gęstości. Rozmiar obrazów w tych katalogach rysowalnych jest dostosowywany do konkretnej 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
, będzie 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.
Uwaga: określając zasób alternatywny, musisz też zdefiniować go w konfiguracji domyślnej. W przeciwnym razie, gdy urządzenie zmieni konfigurację, aplikacja może napotkać wyjątki związane ze środowiskiem wykonawczym. Jeśli na przykład dodasz ciąg znaków tylko do values-en
, a nie do values
, Twoja aplikacja może napotkać wyjątek Resource Not Found
, gdy użytkownik zmieni domyślny język systemu.
W tabeli 2 znajdziesz prawidłowe kwalifikatory konfiguracji uporządkowane w kolejności ich obowiązywania. Do nazwy katalogu można dodać wiele kwalifikatorów, rozdzielając je łącznikiem. Jeśli używasz wielu kwalifikatorów dla katalogu zasobów, musisz je dodać do nazwy katalogu w kolejności, w jakiej są wymienione w tabeli.
Konfiguracja | Wartości kwalifikatora | Opis |
---|---|---|
MCK i MNC | Przykłady:mcc310
mcc208-mnc00
|
Kod kraju sieci komórkowej (MCK), opcjonalnie wraz z kodem sieci komórkowej (MNC)
z karty SIM w urządzeniu. Na przykład Jeśli urządzenie korzysta z połączenia radiowego (czyli jest to telefon GSM), wartości MCK i MNC pochodzą z karty SIM. Możesz też użyć samego konta MCK, np. dodać do aplikacji materiały prawne obowiązujące w poszczególnych krajach. Jeśli musisz określić coś tylko na podstawie języka, użyj kwalifikatora języka, skryptu (opcjonalnie) i regionu (opcjonalnie). Jeśli używasz kwalifikatora MCK i MNC, rób to ostrożnie i sprawdź, czy działa zgodnie z oczekiwaniami. Zapoznaj się też z polami konfiguracji |
Język, skrypt (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 za pomocą dwuliterowego kodu języka w formacie ISO 639-1, po którym następuje opcjonalnie dwuliterowy kod regionu ISO 3166-1-alpha-2 (z przedrostkiem „ Wielkość liter w kodach nie jest rozróżniana. Prefiks W Androidzie 7.0 (poziom interfejsu API 24) wprowadzono obsługę tagów języka BCP 47, których możesz używać do kwalifikowania zasobów w zależności od języka i regionu. Tag języka składa się z sekwencji co najmniej 1 tagu podrzędnego, z których każdy zawęża lub zawęża zakres języka zidentyfikowanego przez tag. Więcej informacji o tagach języka znajdziesz w artykule Tagi do identyfikowania języków. Aby użyć tagu języka BCP 47, połącz
Tag języka może się zmienić w trakcie działania aplikacji, jeśli użytkownik zmieni swój język w ustawieniach systemu. Informacje o tym, jak może to wpływać na aplikację w trakcie działania, znajdziesz w sekcji Obsługa zmian konfiguracji. Pełny przewodnik po lokalizowaniu aplikacji na potrzeby innych języków znajdziesz w artykule Lokalizowanie aplikacji. Zapoznaj się też z metodą |
Kierunek układu | ldrtl ldltr |
Kierunek układu aplikacji. Możesz to zrobić w przypadku dowolnych zasobów, takich jak układy, obiekty rysowane i wartości. Jeśli na przykład chcesz określić konkretny układ dla języka arabskiego i ogólny układ dla innych języków pisanych od prawej do lewej, np. perskiego lub hebrajskiego, użyj katalogów w ten sposób:
Uwaga: aby włączyć w aplikacji funkcje układu od prawej do lewej, ustaw Dodano w interfejsie API na poziomie 17. |
Najmniejsza szerokość | sw<N>dp Przykłady: sw320dp sw600dp sw720dp itp. |
Najkrótszy obszar ekranu dostępny dla aplikacji.
Jeśli np. Twój układ wymaga, aby najmniejszy obszar ekranu zawsze miał wielkość co najmniej 600 dp, możesz użyć tego kwalifikatora, aby utworzyć zasoby układu w katalogu Użycie najmniejszej szerokości do określenia ogólnego rozmiaru ekranu jest przydatne, bo jest ona często czynnikiem wpływającym na projekt układu. Interfejs często przewija się w pionie, ale ma dość rygorystyczne ograniczenia dotyczące minimalnej ilości miejsca potrzebnego w poziomie. Dostępna szerokość ma też decydujące znaczenie przy wyborze układu z 1 panelem w przypadku telefonów lub z wieloma panelami w przypadku tabletów. Dlatego też pewnie zależy Ci na najmniejszej możliwej szerokości na każdym z urządzeń. Najmniejsza szerokość urządzenia uwzględnia dekoracje ekranu i interfejs systemu. Jeśli na przykład na ekranie urządzenia znajdują się stałe elementy interfejsu, które zajmują przestrzeń wzdłuż osi o najmniejszej szerokości, system deklaruje najmniejszą szerokość niż rzeczywisty rozmiar ekranu, ponieważ są to piksele ekranu niedostępne w Twoim interfejsie. Niektóre wartości, których możesz użyć w przypadku typowych rozmiarów ekranu:
Gdy aplikacja udostępnia wiele katalogów zasobów z różnymi wartościami kwalifikatora Dodano w interfejsie API na poziomie 13. Zapoznaj się też z atrybutem Więcej informacji o projektowaniu na różne ekrany z wykorzystaniem tego kwalifikatora znajdziesz w artykule o projektowaniu elastycznym/adaptacyjnym 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 jednostkach Dostępne szerokości i wysokości są często przydatne przy ustalaniu, czy zastosować układ z wieloma panelami. Nawet na tablecie często nie chcesz mieć tego samego układu wielu paneli w orientacji pionowej, jak w orientacji poziomej. Dzięki temu możesz określić minimalną szerokość lub wysokość wymaganą w układzie, zamiast używać jednocześnie kwalifikatorów rozmiaru i orientacji ekranu. Gdy aplikacja udostępnia wiele katalogów zasobów z różnymi wartościami na potrzeby tych konfiguracji, system użyje katalogu znajdującego się najbliżej bieżącej szerokości ekranu urządzenia (bez przekraczania). Wartość Najbliższa do jest określana przez dodanie różnic między rzeczywistą i podaną szerokością ekranu do różnicy między rzeczywistą wysokością ekranu a określoną wysokością. Przy nieokreślonych wysokościach i szerokościach wartość wynosi 0. Wartości nie obejmują obszaru zajmowanego przez
ustawienia okien. Jeśli więc urządzenie ma stałe elementy interfejsu na krawędziach wyświetlacza, wartości szerokości i wysokości są mniejsze niż rzeczywiste wymiary ekranu, nawet jeśli aplikacja jest wyświetlana od krawędzi do krawędzi za pomocą funkcji
Niektóre nieutrwalone pionowe dekoracje ekranu (np. pasek stanu telefonu, który można ukryć na pełnym ekranie) nie są tu uwzględniane. Nie dotyczy to też dekoracji okien, takich jak pasek tytułu czy pasek działań. Aplikacje muszą być więc przygotowane na użycie miejsca nieco mniejszego niż określona przez użytkownika. 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, jest zdecydowanie preferowany w stosunku do zasobu, który określa tylko jeden z nich. Jeśli na przykład rzeczywisty ekran ma szerokość 720 dp i wysokość 1280 dp, a jeden zasób jest zakwalifikowanych jako w720dp, a inny jako w700dp-h1200dp, ten drugi zostanie wybrany, mimo że pierwszy zasób dokładnie odpowiada jego wskazaniom. Dodano w interfejsie API na poziomie 13. Zapoznaj się też z polami konfiguracji Więcej informacji o projektowaniu na różne ekrany z wykorzystaniem tego kwalifikatora znajdziesz w artykule o projektowaniu elastycznym/adaptacyjnym z użyciem widoków. |
Rozmiar ekranu |
small normal large xlarge
|
Uwaga: użycie kwalifikatora rozmiaru nie oznacza, że zasoby są przeznaczone tylko na ekrany o tej wielkości. Jeśli nie podasz alternatywnych zasobów z kwalifikatorami, które lepiej pasują do bieżącej konfiguracji urządzenia, system będzie mógł korzystać z zasobów, które są najlepsze. Uwaga: jeśli wszystkie zasoby korzystają z kwalifikatora rozmiaru, który jest większy niż bieżący ekran, system nie będzie ich używać, a aplikacja ulegnie awarii w czasie działania. Dzieje się tak na przykład wtedy, gdy wszystkie zasoby układu są oznaczone kwalifikatorem Dodano w interfejsie API na poziomie 4. Zapoznaj się też z polem konfiguracji Więcej informacji znajdziesz w artykule Omówienie zgodności ekranu. |
Proporcje ekranu |
long notlong
|
Dodano w interfejsie API na poziomie 4. Zależy to wyłącznie od proporcji ekranu (ekran Zapoznaj się też z polem konfiguracji |
Okrągły ekran |
round notround
|
Dodano w interfejsie API na poziomie 23. Zapoznaj się też z metodą konfiguracji |
Szeroki gama kolorów |
widecg nowidecg
|
Dodano w interfejsie API na poziomie 26. Zapoznaj się też z metodą konfiguracji |
HDR (High Dynamic Range) |
highdr lowdr
|
Dodano w interfejsie API na poziomie 26. Zapoznaj się też z metodą konfiguracji |
Orientacja ekranu |
port land
|
Może się to zmienić w okresie życia aplikacji, jeśli użytkownik obróci ekran. Informacje o tym, jak wpłynie to na aplikację w trakcie działania, znajdziesz w sekcji Obsługa zmian konfiguracji. Zapoznaj się też z polem konfiguracji |
Tryb UI |
car desk television appliance watch vrheadset
|
Dodano w interfejsie API na poziomie 8; telewizor dodany w interfejsie API 13; oglądanie zostało dodane w interfejsie API 20. Informacje o reagowaniu aplikacji po umieszczeniu urządzenia w stacji dokującej lub jego usunięciu ze stacji dokującej znajdziesz w artykule Określanie i monitorowanie stanu i typu dokowania. Może się to zmienić w trakcie życia aplikacji, jeśli użytkownik umieści urządzenie w stacji dokującej. Niektóre z tych trybów możesz włączyć lub wyłączyć za pomocą |
Tryb nocny |
night notnight
|
Dodano w interfejsie API na poziomie 8. Może się to zmieniać w trakcie działania aplikacji, jeśli tryb nocny jest pozostawiony 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) |
ldpi mdpi hdpi xhdpi xxhdpi xxxhdpi nodpi tvdpi anydpi nnndpi
|
Między 6 gęstościami podstawowymi występuje współczynnik skalowania 3:4:6:8:12:16 (z pominięciem gęstości tvdpi). Oznacza to, że mapa bitowa 9 x 9 w ldpi ma rozmiar 12 x 12 w mdpi, 18 x 18 w hdpi, 24 x 24 w xhdpi itd. Uwaga: użycie kwalifikatora gęstości nie oznacza, że zasoby są przeznaczone tylko dla ekranów o takiej gęstości. Jeśli nie udostępnisz alternatywnych zasobów z kwalifikatorami, które lepiej pasują do bieżącej konfiguracji urządzenia, system użyje tych, które najlepiej pasują. Więcej informacji o obsłudze różnych gęstości ekranu oraz o możliwości skalowania map bitowych przez Androida w celu dopasowania do bieżącej gęstości znajdziesz w artykule Omówienie zgodności ekranu. |
Typ ekranu dotykowego |
notouch finger
|
Zapoznaj się też z polem konfiguracji |
Dostępność klawiatury |
keysexposed keyshidden keyssoft
|
Jeśli udostępnisz zasoby Może się to zmienić w okresie życia aplikacji, jeśli użytkownik otworzy klawiaturę sprzętową. Informacje o tym, jak wpłynie to na aplikację w trakcie działania, znajdziesz w sekcji Obsługa zmian konfiguracji. Zapoznaj się też z polami konfiguracji |
Podstawowa metoda wprowadzania tekstu |
nokeys qwerty 12key
|
Zapoznaj się też z polem konfiguracji |
Dostępność klawisza nawigacyjnego |
navexposed navhidden
|
Może się to zmienić w trakcie życia aplikacji, jeśli użytkownik ujawni klawisze nawigacyjne. Informacje o tym, jak wpłynie to na aplikację w trakcie działania, znajdziesz w sekcji Obsługa zmian konfiguracji. Zapoznaj się też z polem konfiguracji |
Główna metoda nawigacji bezdotykowej |
nonav dpad trackball wheel
|
Zapoznaj się też z polem konfiguracji |
Wersja platformy (poziom interfejsu API) | Przykłady:v3 v4 v7 itp. |
Poziom interfejsu API obsługiwany przez urządzenie. Na przykład |
Uwaga: nie wszystkie wersje Androida obsługują wszystkie kwalifikatory. Użycie nowego kwalifikatora powoduje domyślnie dodanie kwalifikatora wersji platformy, aby starsze urządzenia mogły go ignorować. Na przykład użycie kwalifikatora w600dp
automatycznie uwzględnia kwalifikator v13
, ponieważ jest on nowy na poziomie 13 interfejsu API. Aby uniknąć problemów, zawsze dodawaj zbiór zasobów domyślnych (zbiór zasobów bez kwalifikatorów). Więcej informacji znajdziesz w sekcji na temat zapewniania najlepszej zgodności urządzeń z zasobami.
Reguły nazwy kwalifikatora
Oto kilka reguł dotyczących nazw kwalifikatorów konfiguracji:
- Możesz określić wiele kwalifikatorów dla jednego zbioru zasobów rozdzielonych myślnikami. Na przykład właściwość
drawable-en-rUS-land
odnosi się do urządzeń w orientacji poziomej (USA i język angielski). - Kwalifikatory muszą być wymienione w tabeli 2.
- Błąd:
drawable-hdpi-port/
- Poprawnie:
drawable-port-hdpi/
- Błąd:
- Alternatywne katalogi zasobów nie mogą być zagnieżdżone. Na przykład nie możesz użyć
res/drawable/drawable-en/
. - Wielkość liter w wartościach nie jest rozróżniana. Kompilator zasobów konwertuje nazwy katalogów na małe litery przed przetwarzaniem, aby uniknąć problemów w systemach plików, w których wielkość liter nie jest rozróżniana. Używanie wielkich liter w nazwie ma jedynie zwiększyć czytelność.
- Obsługiwana jest tylko jedna wartość dla każdego typu kwalifikatora. Jeśli na przykład chcesz użyć tych samych plików rysowalnych dla 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 zgodnie z opisem w sekcji Tworzenie zasobów aliasów.
Gdy zapiszesz zasoby alternatywne w katalogach z tymi kwalifikatorami, Android automatycznie zastosuje je w aplikacji na podstawie bieżącej konfiguracji urządzenia. Przy każdym żądaniu zasobu Android sprawdza alternatywne katalogi zasobów zawierające żądany plik zasobów, a następnie wyszukuje zasób, który najlepiej pasuje.
Jeśli nie ma zasobów alternatywnych, które pasowałyby do określonej konfiguracji urządzenia, Android używa odpowiednich zasobów domyślnych, czyli zbioru 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ć na potrzeby 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 alternatywnym katalogu zasobów. Zamiast tego możesz utworzyć alternatywny zasób działający jako alias dla zasobu zapisanego w domyślnym katalogu zasobów.
Uwaga: nie wszystkie zasoby oferują mechanizm umożliwiający utworzenie aliasu innego zasobu. W szczególności nie są one dostępne w przypadku animacji, menu, nieprzetworzonych danych i innych nieokreślonych zasobów w katalogu xml/
.
Załóżmy, że masz ikonę aplikacji icon.png
i potrzebujesz jej unikalnej wersji dla różnych języków. Jednak w dwóch językach: angielskim i kanadyjskim oraz francusko-kanadyjskim – muszą korzystać z tej samej wersji. Nie musisz kopiować do katalogu zasobów tego samego obrazu
zarówno w języku angielskim-kanadyjskim, jak i francuskim.
Zamiast tego możesz zapisać obraz używany w obu usługach, używając dowolnej nazwy innej niż
icon.png
, takiej jak icon_ca.png
, i umieścić go w domyślnym katalogu res/drawable/
. Następnie w res/drawable-en-rCA/
i res/drawable-fr-rCA/
utwórz plik icon.xml
odwołujący się do zasobu icon_ca.png
za pomocą elementu <bitmap>
. Dzięki temu możesz zapisać tylko jedną wersję pliku PNG i 2 małe pliki XML, które do niego prowadzą. Szczegółowe przykłady znajdziesz w sekcjach poniżej.
Rysowa
Aby utworzyć alias istniejącego elementu, który można przeciągnąć, 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, takim jak res/values-en-rCA/
, zostanie on skompilowany do zasobu, do którego możesz się odwołać jako R.drawable.icon
, ale w rzeczywistości będzie to alias zasobu R.drawable.icon_ca
, który jest zapisany w res/drawable/
.
Układ
Aby utworzyć alias dla istniejącego układu, użyj elementu <include>
umieszczonego 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 do zasobu, do którego można się odwołać jako R.layout.main
, ale w rzeczywistości będzie on aliasem zasobu R.layout.main_ltr
.
Ciągi znaków i inne proste wartości
Aby utworzyć alias istniejącego ciągu znaków, jako wartości nowego ciągu użyj identyfikatora zasobu żądanego ciągu:
<?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 usługi R.string.hello
.
Inne proste wartości działają w ten sam sposób, na przykład kolory:
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="red">#f00</color> <color name="highlight">@color/red</color> </resources>
Uzyskiwanie dostępu do zasobów aplikacji
Po podaniu zasobu w aplikacji możesz go zastosować, podając jego identyfikator. Wszystkie identyfikatory zasobów są zdefiniowane w klasie R
projektu, którą narzędzie aapt
generuje automatycznie.
Po skompilowaniu aplikacji aapt
generuje klasę R
, która zawiera identyfikatory zasobów wszystkich zasobów w katalogu res/
. Dla każdego typu zasobu istnieje podklasa R
, np. R.drawable
, obejmująca wszystkie rysowalne zasoby. Dla każdego zasobu tego typu istnieje statyczna liczba całkowita, np. R.drawable.icon
. Ta liczba całkowita to identyfikator zasobu, którego możesz użyć do jego pobrania.
Chociaż klasa R
określa identyfikatory zasobów, nie trzeba jej 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
,drawable
ilayout
. Więcej informacji o różnych typach zasobów znajdziesz w artykule Omówienie typów zasobów. - Nazwa zasobu, czyli nazwa pliku z wyłączeniem rozszerzenia lub wartość w atrybucie XML
android:name
w przypadku zasobów o prostej wartości, np. ciągu znaków.
Dostęp do zasobu możesz uzyskać na 2 sposoby:
- W kodzie: przy użyciu statycznej liczby całkowitej z podklasy klasy
R
, np.R.string.hello
string
to typ zasobu, ahello
to nazwa zasobu. Gdy podasz identyfikator zasobów w tym formacie, wiele interfejsów API na Androida ma dostęp do Twoich zasobów. Więcej informacji znajdziesz w sekcji Uzyskiwanie dostępu do zasobów w kodzie. - W formacie XML: użyj specjalnej składni XML, która odpowiada identyfikatorowi zasobu zdefiniowanemu w klasie
R
, np.@string/hello
string
to typ zasobu, ahello
to nazwa zasobu. Tej składni możesz użyć w zasobie XML w dowolnym miejscu, w którym oczekiwana jest wartość podana w zasobie. Więcej informacji znajdziesz w sekcji Uzyskiwanie dostępu do zasobów z pliku XML.
Dostęp do zasobów w kodzie
Aby użyć zasobu w kodzie, przekaż jego identyfikator jako parametr metody. Możesz na przykład ustawić ImageView
tak, 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óre można pobrać za pomocą metody getResources()
.
Składnia
Składnia, która pozwala odwoływać 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 Twojego pakietu).<resource_type>
jest podklasąR
typu zasobu.<resource_name>
to nazwa pliku zasobu bez rozszerzenia lub wartość atrybutuandroid:name
w elemencie XML w przypadku prostych wartości.
Więcej informacji o poszczególnych typach zasobów i o tym, jak się do nich odwołać, znajdziesz w artykule Omówienie typów zasobów.
Przykłady zastosowań
Jest wiele metod, które akceptują parametr identyfikatora zasobu. Możesz pobierać zasoby za pomocą metod w interfejsie Resources
. Możesz pobrać instancję Resources
za pomocą Context.getResources()
.
Oto kilka przykładów uzyskiwania 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);
Uwaga: nie modyfikuj pliku R.java
ręcznie. Jest generowany przez narzędzie aapt
podczas kompilowania projektu. Wszystkie zmiany zostaną zastąpione podczas następnej kompilacji.
Dostęp do zasobów z pliku XML
Wartości niektórych atrybutów i elementów XML można definiować, korzystając z odwołania do istniejącego zasobu. Często robi się tak przy tworzeniu plików układu, aby dobierać ciągi i obrazy do widżetów.
Jeśli na przykład dodasz do układu element Button
, użyj zasobu w postaci ciągu dla tekstu przycisku:
<Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/submit" />
Składnia
Oto składnia pozwalająca odwoływać się 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 to wymagane, gdy odwołujesz się do zasobów z tego samego pakietu).<resource_type>
to podklasa typu zasobuR
.<resource_name>
to nazwa pliku zasobu bez rozszerzenia lub wartość atrybutuandroid:name
w elemencie XML w przypadku prostych wartości.
Więcej informacji o poszczególnych typach zasobów i o tym, jak się do nich odwołać, znajdziesz w artykule Omówienie typów zasobów.
Przykłady zastosowań
W niektórych przypadkach musisz użyć zasobu dla wartości w pliku XML, na przykład aby zastosować rysowalny obraz do widżetu, ale zasobu w formacie XML możesz też użyć w dowolnym miejscu, które akceptuje prostą wartość. Załóżmy na przykład, że masz plik zasobów zawierający zasób koloru i zasób w postaci ciągu znaków:
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="opaque_red">#f00</color> <string name="hello">Hello!</string> </resources>
Możesz użyć tych zasobów w tym pliku układu, 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 określać nazwy pakietu w informacjach o zasobach, bo 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 w postaci ciągów znaków, aby umożliwić zlokalizowanie aplikacji na inne języki. Informacje o tworzeniu zasobów alternatywnych (takich jak zlokalizowane ciągi znaków) znajdziesz w sekcji Udostępnianie zasobów alternatywnych. Pełny przewodnik po lokalizowaniu aplikacji na potrzeby innych języków znajdziesz w artykule Lokalizowanie aplikacji.
Do tworzenia aliasów możesz nawet używać zasobów w języku XML. Możesz na przykład utworzyć rysowalny zasób będący aliasem innego rysowalnego zasobu:
<?xml version="1.0" encoding="utf-8"?> <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/other_drawable" />
Wygląda to nadmiernie, ale może być bardzo przydatne, gdy korzystasz z alternatywnych zasobów. Więcej informacji znajdziesz w sekcji dotyczącej tworzenia zasobów aliasów.
Atrybuty stylu odwołania
Zasób atrybutu stylu pozwala odwołać się do wartości atrybutu w aktualnie stosowanym motywie. Odwoływanie się do atrybutu stylu pozwala dostosować wygląd elementów interfejsu przez dostosowywanie ich stylu do standardowych odmian dostarczanych przez bieżący motyw, zamiast podawania wartości zakodowanej na stałe. Odwołanie do atrybutu stylu brzmi w zasadzie: „Użyj stylu zdefiniowanego przez ten atrybut w bieżącym motywie”.
Aby odwołać się do atrybutu stylu, składnia nazwy jest prawie identyczna jak zwykły format zasobów, ale zamiast symbolu „at” (@
) użyj znaku zapytania (?
). Część typu zasobu jest opcjonalna. Składnia referencji będzie więc wyglądać tak:
?[<package_name>:][<resource_type>/]<resource_name>
Oto przykład odwołania do atrybutu, który pozwala ustawić kolor tekstu tak, aby pasował do dodatkowego koloru tekstu w motywie systemowym:
<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 atrybutu stylu android:textColorSecondary
jako wartości atrybutu android:textColor
w tym widżecie. Narzędzie do zasobów systemowych wie, że zasób atrybutu jest oczekiwany w tym kontekście, dlatego nie musisz wyraźnie określać jego typu, którym jest ?android:attr/textColorSecondary
. Możesz wykluczyć typ attr
.
Dostęp do oryginalnych plików
Nie jest to regułą, ale może być konieczne uzyskanie dostępu do oryginalnych plików i katalogów. Jeśli to zrobisz, zapisanie plików w usłudze res/
nie zadziała, ponieważ jedyny sposób odczytania zasobu z res/
to użycie identyfikatora zasobu. Zamiast tego możesz zapisywać zasoby w katalogu assets/
.
Pliki zapisane w katalogu assets/
nie mają identyfikatora zasobu, więc nie można odwoływać się do nich za pomocą klasy R
ani zasobów XML. Zamiast tego możesz tworzyć zapytania dotyczące plików w katalogu assets/
jak w przypadku zwykłego systemu plików i odczytywać nieprzetworzone dane za pomocą narzędzia AssetManager
.
Jeśli jednak potrzebujesz jedynie możliwości odczytu nieprzetworzonych danych (np. pliku wideo lub audio), zapisz plik w katalogu res/raw/
i odczytaj strumień bajtów za pomocą narzędzia 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, musisz zakwalifikować odwołanie do zasobu za pomocą nazwy pakietu android
. Na przykład Android zapewnia zasób układu, którego można użyć na potrzeby elementów listy w elemencie 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
jest zasobem układu zdefiniowanym przez platformę dla elementów w obiekcie ListView
. Możesz go użyć zamiast
tworzyć własny układ elementów listy.
Zapewnij największą zgodność urządzeń z zasobami
Aby aplikacja obsługiwała wiele konfiguracji urządzeń, ważne jest, aby dla każdego typu zasobów używanych przez aplikację zawsze udostępniać zasoby domyślne.
Jeśli na przykład aplikacja obsługuje kilka języków, zawsze dodawaj katalog values/
(w którym zapisywane są ciągi znaków) bez kwalifikatora języka i regionu. Jeśli zamiast tego umieścisz wszystkie pliki ciągu znaków w katalogach z kwalifikatorem języka i regionu, aplikacja ulegnie awarii, gdy zostanie uruchomiona na urządzeniu z językiem, którego ciągi nie obsługują.
Jeśli podasz domyślne zasoby values/
, aplikacja będzie działać prawidłowo, nawet jeśli użytkownik nie rozumie przedstawianego języka. To lepsze niż awaria.
Podobnie, jeśli udostępniasz różne zasoby układu w zależności od orientacji ekranu, wybierz jedną z nich jako domyślną. Na przykład zamiast podawać zasoby układu w języku layout-land/
dla orientacji poziomej i layout-port/
dla orientacji pionowej, pozostaw wartość domyślną – np. layout/
dla orientacji poziomej i layout-port/
dla orientacji pionowej.
Podanie zasobów domyślnych jest ważne nie tylko dlatego, że aplikacja może działać w nieoczekiwanej konfiguracji, ale także 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ę, a jeśli nie podasz zasobów domyślnych, spowoduje to awarię, ponieważ nie będzie ona mogła korzystać z zasobów wymienionych na podstawie nowego kwalifikatora.
Jeśli na przykład wartość minSdkVersion
ma wartość 4 i kwalifikujesz się do korzystania ze wszystkich rysowalnych zasobów w trybie nocnym (night
lub notnight
, które zostały dodane na poziomie 8 interfejsu API), urządzenie API poziomu 4 nie może uzyskać dostępu do tych zasobów i awarii. W takim przypadku Twoim domyślnym zasobem może być notnight
, więc wyklucz ten kwalifikator i umieść rysowalne zasoby w polu drawable/
lub drawable-night/
.
Krótko mówiąc, aby zapewnić jak największą zgodność z urządzeniami, zawsze udostępniaj domyślne zasoby zasobów, których aplikacja potrzebuje do prawidłowego działania. Następnie utwórz alternatywne zasoby dla konkretnych konfiguracji urządzeń za pomocą kwalifikatorów konfiguracji.
Od tej reguły jest 1 wyjątek: jeśli parametr minSdkVersion
Twojej aplikacji ma wartość 4 lub większą, nie potrzebujesz domyślnych zasobów, które można przeciągać, gdy udostępniasz alternatywne zasoby rysowalne za pomocą kwalifikatora gęstości ekranu. Nawet bez domyślnych zasobów rysowanych Android może znaleźć najlepsze dopasowanie spośród alternatywnych gęstości ekranu i w razie potrzeby skalować mapy bitowe. Aby jednak uzyskać najlepsze wrażenia na wszystkich typach urządzeń, zapewnij alternatywne elementy rysowane na potrzeby wszystkich 3 typów gęstości.
Jak Android znajduje najlepszy zasób
Gdy prosisz o zasób, dla którego udostępniasz zasoby alternatywne, Android wybiera ten zasób w czasie działania w zależności od bieżącej konfiguracji urządzenia. Aby pokazać, jak Android wybiera alternatywny zasób, załóżmy, że każdy z nich zawiera 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/
Przyjmijmy też taką konfigurację urządzenia:
Język = en-GB
Orientacja ekranu = port
Gęstość pikseli ekranu = 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ę, których zasobów użyć, korzystając z następującej logiki:
- Usuń pliki zasobów, które są sprzeczne z konfiguracją urządzenia.
Katalog
drawable-fr-rCA/
został wyeliminowany, ponieważ jest sprzeczny z językiemen-GB
.drawable/ drawable-en/
drawable-fr-rCA/drawable-en-port/ drawable-en-notouch-12key/ drawable-port-ldpi/ drawable-port-notouch-12key/Wyjątek: jedyny kwalifikator, który nie jest eliminowany ze względu na sprzeczność, to gęstość pikseli na ekranie. Chociaż gęstość ekranu urządzenia jest hdpi,
drawable-port-ldpi/
nie jest usuwana, ponieważ w tym momencie każda gęstość ekranu jest uznawana za pasującą. Więcej informacji znajdziesz w artykule Omówienie zgodności ekranu. - Znajdź na liście kwalifikator o następnym najwyższym priorytecie (tabela 2). (Rozpocznij od MCK).
- Czy którykolwiek z katalogów zasobów zawiera ten kwalifikator?
- Jeśli nie, wróć do kroku 2 i sprawdź kolejne kwalifikacje. W tym przykładzie odpowiedź brzmi „nie”, dopóki nie zostanie osiągnięty kwalifikator języka.
- Jeśli tak, przejdź do kroku 4.
- Usuń katalogi zasobów, które nie zawierają tego kwalifikatora. W tym przykładzie funkcja Następne 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 to gęstość pikseli ekranu, Android wybiera opcję, która najlepiej pasuje do gęstości ekranu urządzenia. Ogólnie rzecz biorąc, Android woli zmniejszać rozmiar oryginalnego obrazu, aby pomniejszać go w górę. Więcej informacji znajdziesz w artykule Omówienie zgodności ekranu.
- Powtórz kroki 2, 3 i 4, aż pozostanie tylko jeden katalog. W tym przykładzie kolejnym kwalifikatorem, w przypadku którego występują dopasowania, jest orientacja ekranu.
Z tego powodu zasoby, które nie mają określonej orientacji ekranu, są eliminowane:
drawable-en/drawable-en-port/drawable-en-notouch-12key/Pozostały katalog to
drawable-en-port
.
Procedura ta jest wykonywana dla każdego żądanego zasobu, ale system optymalizuje niektóre aspekty. Jedną z takich optymalizacji jest to, że znana konfiguracja urządzenia może wyeliminować alternatywne zasoby, które nigdy nie będą do siebie pasować. Jeśli na przykład językiem konfiguracji jest język angielski, to każdy katalog zasobów z kwalifikatorem języka innym niż angielski nie będzie nigdy uwzględniany w puli sprawdzonych zasobów (chociaż 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 dla ekranu mniejszego niż bieżący, jeśli nie ma zasobów, które lepiej pasowałyby do ekranu. Na przykład na dużym ekranie w razie potrzeby są używane zasoby ekranu o normalnej wielkości.
Jeśli jednak jedyne dostępne zasoby są większe niż bieżący ekran, system nie z nich korzysta, a aplikacja ulega awarii, gdy żadne inne zasoby nie pasują do konfiguracji urządzenia. Dzieje się tak na przykład wtedy, gdy wszystkie zasoby układu są oznaczone kwalifikatorem xlarge
, ale urządzenie ma normalny rozmiar.
Uwaga: wcześniejsza kolejność kwalifikatora (w tabeli 2) jest ważniejsza niż liczba kwalifikatorów, które dokładnie odpowiadają urządzeniu. W poprzednim przykładzie w kroku 4 ostatnia opcja na liście zawiera 3 kwalifikatory dokładnie dopasowane do urządzenia (orientacja, typ ekranu dotykowego i metoda wprowadzania), a drawable-en
ma tylko 1 pasujący parametr (język). Język ma jednak wyższy priorytet niż inne kwalifikatory, więc właściwość drawable-port-notouch-12key
jest usuwana.