Odwołanie do ciągu w zasobie tablicy ciągów za pomocą xml


256

Mam preferencje, w których możesz włączyć / wyłączyć, które elementy pojawią się w menu. Jest 17 pozycji. Zrobiłem tablicę ciągów w wartości / arrays.xml z tytułami dla każdego z tych 17 elementów.

Mam plik preferencji.xml, który ma układ mojego pliku preferencji, i chciałbym odwoływać się do jednego elementu z tablicy ciągów, który mógłby zostać użyty jako tytuł.

W jaki sposób mogę to zrobić?

W dokumentacji dla programistów Androida widzę, w jaki sposób mogę odwoływać się do pojedynczego ciągu za pomocą XML, ale nie w jaki sposób mogę odwoływać się do ciągu z zasobu tablicy w XML.

Odpowiedzi:


331

W skrócie: Nie sądzę, że można, ale nie wydaje się być obejście: .

Jeśli spojrzysz na Zasób Androida tutaj:

http://developer.android.com/guide/topics/resources/string-resource.html

Widzisz, niż pod sekcją tablic (przynajmniej tablica ciągów), „REFERENCJA ZASOBÓW” (jak otrzymujesz z XML) nie określa sposobu adresowania poszczególnych elementów. Możesz nawet wypróbować w swoim XML użycie „@ array / yourarrayhere”. Wiem, że w czasie projektowania dostaniesz pierwszy przedmiot. Ale to nie ma praktycznego zastosowania, jeśli chcesz użyć, powiedzmy ... drugi, oczywiście.

JEDNAK istnieje sztuczka, którą możesz zrobić. Spójrz tutaj:

Odwoływanie się do ciągu XML w tablicy XML (Android)

Możesz „oszukiwać” (nie bardzo) definicję tablicy, adresując niezależne ciągi WEWNĄTRZ definicji tablicy. Na przykład w pliku strings.xml:

<string name="earth">Earth</string>
<string name="moon">Moon</string>

<string-array name="system">
    <item>@string/earth</item>
    <item>@string/moon</item>
</string-array>

Korzystając z tego, możesz normalnie używać „@ string / earth” i „@ string / moon” w polach XML „android: text” i „android: title”, ale nie stracisz możliwości korzystania z tablicy definicja do jakichkolwiek celów, które zamierzałeś w pierwszej kolejności.

Wydaje się, że działa tutaj na moim Eclipse. Dlaczego nie powiesz nam, czy to działa? :-)


32
gdybyśmy mogli tylko podać nametagi <item> s ... * westchnienie *
Some Noob Student

2
Właśnie tego spróbowałem! Zdefiniowano tablicę w ustawieniach domyślnych, strings.xmlale nie została wprowadzona, values-fra tablica wciąż aktualizowana w wersji francuskiej. Tak źle ... ale fajnie, to działa!
Blundell,

1
Szybka wskazówka dla każdego: podwójne kliknięcie „ziemia” podświetli ziemię. Podwójne kliknięcie na księżyc w @ string / moon podświetli tylko księżyc. Tak więc, jeśli duplikujesz pierwszy element kilka razy podczas budowania tablicy, możesz dość łatwo kopiować i wklejać pomiędzy poszczególnymi łańcuchami i tablicą łańcuchów. Może pomóc w przyspieszeniu tworzenia tablicy ciągów :)
ArtOfWarfare

2
Chcesz tylko wiedzieć, czy to podejście powoduje gorszą wydajność, niż jeśli deklaruję ciągi w tablicy, ponieważ są, ale nie używają referencji?
Alex Bonel

1
@AlexBonel ciekawe pytanie i szczerze mówiąc nie wiem. Nawet gdyby tak było, myślę, że powinniśmy pozostawić ten rodzaj bardzo mikrooptymalizacji kompilatorowi. W każdym razie, czy nie kończą się gdzieś po drodze? Chyba tak, ale nie jestem pewien. Wiem, że przynajmniej na wyższym poziomie w łańcuchu Androida, możesz w pełni zdemontować APK za pomocą apktoola i odzyska on oryginalne nazwy kluczy ciągów, co oznacza, że ​​deklaracje odniesienia, takie jak powyższa, zostaną zachowane. Ale w tej chwili nie jestem bardzo zainteresowany tym obszarem, więc nie mogę odpowiedzieć na twoje pytanie. To dobre pytanie.
davidcsb

216

Może to pomogłoby:

String[] some_array = getResources().getStringArray(R.array.your_string_array)

Otrzymujesz listę tablic jako String [], a następnie wybierasz dowolne i, some_array [i].


10
Rozumiem, jak uzyskać zasób tablicy. To jednak nie pozwala mi odwoływać się do elementu z tablicy w układzie xml.
Jorsher,

1
O przepraszam. Źle zrozumiałem. Czy to musi być układ xml? Jeśli tytuł zmienia się w zależności od wyboru użytkownika, dlaczego nie zrobić tego w pliku .java. Np. .SetText (some_array [i]).

2
Ponieważ układ preferencji jest w formacie xml. Jawa ładuje menu z elementami, które są „włączone” w preferencjach. Wpisanie 17 sprawdza preferencje, a następnie kod, który dodaje go do widoku listy, wydaje mi się zbędny i niechlujny.
Jorsher,

Przydało mi się to, gdy tworzyłem arrayadapter z tablicy xml w moim folderze wartości
EHarpham

Uznałem, że jest to przydatne, gdy potrzebuję wartości domyślnej przy uzyskiwaniu preferencji: String myPref = preferences.getString(context.getResources().getString(R.string.my_pref), some_array [0]);gdzie mój_pref był wcześniej ustawiony na jakąś wartość some_array [x]
Al Lelopath,

67

Lepszą opcją byłoby po prostu użycie tablicy zwróconej przez zasoby jako tablicy, co oznacza:

getResources().getStringArray(R.array.your_array)[position]

Jest to skrótowe podejście do wyżej wymienionych podejść, ale działa w pożądany sposób. W przeciwnym razie Android nie zapewnia bezpośredniego indeksowania XML dla tablic opartych na XML.


1
@ Benjiko99 dzięki za wykrycie błędu, odpowiednio go zmieniłem.
Amitesh

Jest to najbardziej zwięzły sposób na zrobienie tego. +1!
suomi35,

1
może się to wydawać bardziej zwięzłe, ale jeśli ktoś lub tłumacz zmieni kolejność tablicy w pliku łańcuchów, skończysz na użyciu niewłaściwego łańcucha.
newDeveloper

9

Niestety:

  • Wydaje się, że nie można odwoływać się do pojedynczego elementu z tablicy w pliku values ​​/ arrays.xml za pomocą XML. Oczywiście możesz w Javie, ale nie XML. Brak informacji na ten temat w dokumentacji dla programistów Androida i nie mogłem znaleźć nigdzie indziej.

  • Wygląda na to, że nie można użyć tablicy jako klucza w układzie preferencji. Każdy klucz musi być pojedynczą wartością z własną nazwą klucza.

Co chcę osiągnąć: chcę móc przejść przez 17 preferencji, sprawdzić, czy element jest zaznaczony, a jeśli tak, załaduj ciąg z tablicy ciągów dla tej nazwy preferencji.

Oto kod, który miałem nadzieję, że wykona to zadanie:

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());  
ArrayAdapter<String> itemsArrayList = new ArrayAdapter<String>(getBaseContext(),   android.R.layout.simple_list_item_1);  
String[] itemNames = getResources().getStringArray(R.array.itemNames_array);  


for (int i = 0; i < 16; i++) {  
    if (prefs.getBoolean("itemKey[i]", true)) {  
        itemsArrayList.add(itemNames[i]);  
    }  
} 

Co ja zrobiłem:

  • Ustawiłem pojedynczy ciąg dla każdego z elementów i odwołałem się do pojedynczych ciągów w. Używam odwołania do pojedynczego ciągu dla tytułów pól wyboru układu preferencji i tablicy dla mojej pętli.

  • Aby przeglądać preferencje, nazwałem klucze takie jak key1, key2, key3 itd. Ponieważ odwołujesz się do klucza za pomocą łańcucha, masz możliwość „zbudowania” nazwy klucza w czasie wykonywania.

Oto nowy kod:

for (int i = 0; i < 16; i++) {  
        if (prefs.getBoolean("itemKey" + String.valueOf(i), true)) {  
        itemsArrayList.add(itemNames[i]);  
    }  
}

1

Innym sposobem na to jest zdefiniowanie tablicy zasobów w strings.xml, jak poniżej.

<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE resources [
    <!ENTITY supportDefaultSelection "Choose your issue">
    <!ENTITY issueOption1 "Support">
    <!ENTITY issueOption2 "Feedback">
    <!ENTITY issueOption3 "Help">
    ]>

a następnie zdefiniowanie tablicy ciągów przy użyciu powyższych zasobów

<string-array name="support_issues_array">
        <item>&supportDefaultSelection;</item>
        <item>&issueOption1;</item>
        <item>&issueOption2;</item>
        <item>&issueOption3;</item>
    </string-array>

Możesz również odwołać ten sam ciąg do innych plików XML, utrzymując DRY nietknięty. Zaletą, którą widzę, jest to, że zmiana jednej wartości wpłynie na wszystkie odwołania w kodzie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.