Посилання на рядок у ресурсному масиві з xml


256

У мене є налаштування, де ви можете вмикати / вимикати, які елементи відображатимуться в меню. Є 17 предметів. Я створив рядковий масив у значеннях / arrays.xml із заголовками для кожного з цих 17 елементів.

У мене preferences.xml, який має макет файлу моїх налаштувань, і я хотів би посилатися на один елемент із масиву рядків, який використовуватиметься як заголовок.

Як я можу це зробити?

У посиланні для розробників Android я бачу, як я можу посилатися на одну рядок з XML, але не як я можу посилати рядок з ресурсу масиву в XML.

Відповіді:


331

Коротше кажучи: я не думаю , що ви можете, але там , здається, обхідний шлях: .

Якщо ви подивитесь на ресурс Android тут:

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

Ви бачите, ніж під розділом масиву (як мінімум рядковий масив), "РЕФЕРЕНЦІЯ РЕСУРСІВ" (як ви отримуєте з XML) не вказує спосіб адресації окремих елементів. Ви навіть можете спробувати у своєму XML використовувати "@ array / yourarrayhere". Я знаю, що за час проектування ви отримаєте перший предмет. Але це не приносить користі, якщо ви хочете використовувати, скажімо ... друге, звичайно.

ЗАРАЗ, є хитрість, яку ви можете зробити. Дивіться тут:

Посилання на рядок XML у масив XML (Android)

Ви можете «обдурити» (насправді) визначення масиву, звернувшись до незалежних рядків ВНІШНЕ визначення масиву. Наприклад, у вашому 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>

Використовуючи це, ви можете використовувати "@ string / earth" та "@ string / moon" звичайно у своїх полях "android: text" та "android: title" XML, і все ж ви не втратите можливості використовувати масив визначення в будь-яких цілях, які ви задумали в першу чергу.

Здається, працює тут на моєму затемненні. Чому б не спробувати і сказати нам, чи працює це? :-)


32
якби ми могли дати nameтеги лише <item> s ... * зітхання *
Some Noob Student

2
Просто спробував! Визначив масив за замовчуванням, strings.xmlале не ввійшов, values-frі масив все ще оновлювався французькою версією. Так неправильно .. але круто це працює!
Blundell

1
Швидкий підказ для кожного: подвійне клацання на "земля" виділить землю. Подвійне клацання на Місяці в @ рядок / місяць виділить просто місяць. Таким чином, якщо при створенні масиву ви повторюєте перший елемент кілька разів, ви зможете скопіювати та вставити між своїми окремими рядками та рядковим масивом досить легко. Може допомогти прискорити створення вашої струнної масиви :)
ArtOfWarfare

2
Просто хочу знати, чи викликає такий підхід гірші показники, ніж якщо я оголошую рядки в масиві такими, якими вони є, але не використовують посилання?
Алекс Бонель

1
@AlexBonel цікаве питання, і я, чесно кажучи, не знаю. Навіть якби це було, я думаю, що ми повинні залишити такий тип дуже мікрооптимізації компілятору. У будь-якому випадку, вони не закінчуються підкресленими десь у дорозі? Я б здогадався, що вони так роблять, але я не впевнений. Принаймні, на вищому рівні в ланцюзі Android, я знаю, що ви можете повністю розібрати APK за допомогою apktool, і він відновить оригінальні назви рядкових клавіш, а значить, зберігаються посилання на декларації, як і вище. Але зараз я не дуже зацікавлений у цій галузі, тому не можу відповісти на ваше запитання. Хоча це гарне питання.
davidcsb

216

Можливо, це допоможе:

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

Отже, ви отримуєте список масивів як String [], а потім вибираєте будь-який i, some_array [i].


10
Я розумію, як отримати ресурс масиву. Це не дозволяє мені посилатись на елемент з масиву в макеті xml.
Jorsher

1
Ах, вибачте. Я неправильно зрозумів. Ну, чи має бути це у макеті xml? Якщо заголовок змінюється за вибором користувача, чому б просто не зробити це у файлі .java Напр .setText (some_array [i]).

2
Тому що макет налаштувань у xml. Java завантажує меню пунктами, які "увімкнено" у налаштуваннях. Набравши 17 перевірок на налаштування, а подальший код, щоб додати його до списку, мені здається зайвим і неохайним.
Jorsher

Це було корисно, коли я створював масив з масиву xml у папці зі значеннями
EHarpham

Я вважаю це корисним, коли потрібне значення за замовчуванням при отриманні налаштування: String myPref = preferences.getString(context.getResources().getString(R.string.my_pref), some_array [0]);де my_pref раніше було встановлено якесь значення some_array [x]
Al Lelopath

67

Кращим варіантом було б просто використовувати масив, що повернувся ресурсом, як масив, що означає:

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

Це швидкий підхід вищезгаданих підходів, але чи працює так, як ви хочете. В іншому випадку Android не забезпечує пряму індексацію XML для масивів на основі xml.


1
@ Benjiko99 спасибі за виявлення помилки, змінили її відповідно.
Амітеш

Це найбільш стислий спосіб зробити це. +1!
suomi35

1
це може здатися більш стислим, але якщо хтось або перекладач змінить порядок масиву в рядковому файлі, ви в кінцевому підсумку використаєте неправильний рядок.
newDeveloper

9

На жаль:

  • Здається, ви не можете посилатися на один елемент з масиву у значеннях / arrays.xml з XML. Звичайно, можна на Java, але не XML. Немає інформації про це в довідці для розробників Android, і я не міг знайти ніде більше.

  • Здається, ви не можете використовувати масив як ключ у макеті налаштувань. Кожен ключ повинен бути єдиним значенням із власним іменем ключа.

Що я хочу досягти: я хочу мати змогу провести цикл через 17 налаштувань, перевірити, чи перевіряється елемент, і якщо він є, завантажте рядок із масиву рядків для цієї назви переваг.

Ось код, який я сподівався виконати це завдання:

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

Що я зробив:

  • Я встановив один рядок для кожного з елементів і посилався на один рядок у. Я використовую посилання на єдиний рядок для заголовків прапорця макета налаштувань та масив для свого циклу.

  • Щоб переглядати налаштування, я щойно назвав такі ключі, як key1, key2, key3 тощо. Оскільки ви посилаєтесь на ключ із рядком, у вас є можливість "побудувати" ім'я ключа під час виконання.

Ось новий код:

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

1

Інший спосіб зробити це - визначити масив ресурсів у strings.xml, як показано нижче.

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

а потім визначення рядкового масиву за допомогою вищезазначених ресурсів

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

Ви можете вказати ту саму рядок в інші xmls, також зберігаючи DRY недоторканою. Я бачу перевагу в тому, що при зміні одного значення це вплине на всі посилання в коді.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.