Fare riferimento a una stringa in una risorsa array di stringhe con xml


256

Ho delle preferenze in cui è possibile abilitare / disabilitare quali elementi verranno visualizzati nel menu. Ci sono 17 articoli Ho creato una matrice di stringhe in valori / arrays.xml con titoli per ciascuno di questi 17 elementi.

Ho preferenze.xml che ha il layout per il mio file delle preferenze e vorrei fare riferimento a un singolo elemento dell'array di stringhe da utilizzare come titolo.

Come posso fare questo?

Nel riferimento per sviluppatori Android, vedo come posso fare riferimento a una singola stringa con XML, ma non come posso fare riferimento a una stringa da una risorsa array in XML.

Risposte:


331

In breve: non credo che è possibile, ma sembra che ci sia una soluzione: .

Se dai un'occhiata alle risorse Android qui:

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

Si vede che nella sezione array (array di stringhe, almeno), il "RIFERIMENTO RISORSE" (come si ottiene da un XML) non specifica un modo per indirizzare i singoli elementi. Puoi anche provare nel tuo XML per usare "@ array / yourarrayhere". So che in fase di progettazione otterrai il primo oggetto. Ma non serve a niente se vuoi usarlo, diciamo ... il secondo, ovviamente.

TUTTAVIA, c'è un trucco che puoi fare. Vedere qui:

Riferimento a una stringa XML in un array XML (Android)

Puoi "imbrogliare" (non proprio) la definizione di array indirizzando stringhe indipendenti INSIDE alla definizione di array. Ad esempio, nel tuo 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>

Usando questo, puoi usare "@ string / earth" e "@ string / moon" normalmente nei tuoi campi XML "android: text" e "android: title", eppure non perderai la possibilità di usare l'array definizione per qualunque scopo tu intendessi in primo luogo.

Sembra funzionare qui sul mio Eclipse. Perché non provi a dirci se funziona? :-)


32
se solo potessimo dare nametag a <item> s ... * sigh *
Some Noob Student,

2
L'ho appena provato! Definito l'array per impostazione predefinita, strings.xmlma non presente values-fre l'array è ancora aggiornato con la versione francese. Così sbagliato .. ma bello funziona!
Blundell

1
Suggerimento rapido per chiunque: facendo doppio clic su "terra" si evidenzierà la terra. Fare doppio clic sulla luna in @ string / moon per evidenziare solo moon. Pertanto, se si duplica più volte il primo elemento durante la creazione dell'array, è possibile quindi copiare e incollare abbastanza facilmente tra le singole stringhe e l'array di stringhe. Potrebbe esserti utile accelerare la creazione del tuo array di stringhe :)
ArtOfWarfare

2
Voglio solo sapere se questo approccio causa prestazioni peggiori rispetto a quando dichiaro le stringhe nella matrice così come sono ma non utilizzo i riferimenti?
Alex Bonel,

1
@AlexBonel è una domanda interessante, e sinceramente non lo so. Anche se, penso che dovremmo lasciare questo tipo di micro ottimizzazione al compilatore. Comunque, non finiscono in linea da qualche parte in fondo alla strada? Immagino che lo facciano, ma non ne sono sicuro. Almeno a un livello superiore nella catena Android, so che puoi disassemblare completamente un APK con apktool e recupererà i nomi originali delle chiavi di stringa, il che significa che vengono mantenute le dichiarazioni a cui si fa riferimento, come quella sopra. Ma non sono molto interessato a quell'area in questo momento, quindi non posso rispondere alla tua domanda. È una buona domanda però.
davidcsb,

216

Forse questo aiuterebbe:

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

Quindi ottieni l'elenco di array come String [] e quindi scegli qualsiasi i, some_array [i].


10
Capisco come ottenere la risorsa array. Ciò non mi consente di fare riferimento all'elemento dall'array in un layout XML.
Jorsher,

1
Mi dispiace. Ho frainteso. Bene, deve essere nel layout XML? Se il titolo cambia con la scelta dell'utente, perché non farlo nel file .java. Ad esempio .setText (some_array [i]).

2
Perché, il layout delle preferenze è in xml. Java carica il menu con le voci "abilitate" nelle preferenze. Digitando 17 controlla le preferenze e il codice successivo per aggiungerlo alla lista sembra ridondante e sciatto per me.
Jorsher,

Questo è stato utile quando stavo creando un arrayadapter da un array xml nella mia cartella dei valori
EHarpham,

L'ho trovato utile quando avevo bisogno di un valore predefinito quando String myPref = preferences.getString(context.getResources().getString(R.string.my_pref), some_array [0]);ottenevo una preferenza: dove my_pref era precedentemente impostato su un valore some_array [x]
Al Lelopath,

67

L'opzione migliore sarebbe quella di utilizzare l'array restituito come risorsa come array, ovvero:

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

Questo è un approccio di scelta rapida degli approcci sopra menzionati, ma fa il lavoro nel modo desiderato. Altrimenti Android non fornisce l'indicizzazione XML diretta per array basati su XML.


1
@ Benjiko99 grazie per aver individuato l'errore, l'ho modificato di conseguenza.
Amitesh,

Questo è il modo più conciso per farlo. +1!
suomi35,

1
questo può sembrare più conciso, ma se qualcuno o il traduttore cambiano l'ordine dell'array nel file stringhe, finirai per usare la stringa sbagliata.
newDeveloper

9

Sfortunatamente:

  • Sembra che non sia possibile fare riferimento a un singolo elemento di una matrice in valori / arrays.xml con XML. Certo che puoi in Java, ma non in XML. Non ci sono informazioni su come farlo nel riferimento per gli sviluppatori Android e non sono riuscito a trovare altrove.

  • Sembra che non sia possibile utilizzare un array come chiave nel layout delle preferenze. Ogni chiave deve essere un valore singolo con il proprio nome chiave.

Cosa voglio ottenere: voglio essere in grado di scorrere le 17 preferenze, verificare se l'elemento è selezionato e, in tal caso, caricare la stringa dall'array di stringhe per quel nome di preferenza.

Ecco il codice che speravo potesse completare questa attività:

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

Cosa ho fatto:

  • Ho impostato una singola stringa per ciascuno degli elementi e ho fatto riferimento alle singole stringhe in. Uso il riferimento a stringa singola per i titoli della casella di controllo del layout delle preferenze e l'array per il mio loop.

  • Per scorrere le preferenze, ho appena chiamato le chiavi come key1, key2, key3, ecc. Dato che fai riferimento a una chiave con una stringa, hai la possibilità di "costruire" il nome della chiave in fase di esecuzione.

Ecco il nuovo codice:

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

1

Un altro modo per farlo è definire un array di risorse in strings.xml come di seguito.

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

e quindi definire un array di stringhe usando le risorse sopra

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

Potresti riferire la stessa stringa anche in altri xmls mantenendo DRY intatto. Il vantaggio che vedo è che, con una singola modifica del valore, avrebbe effetto su tutti i riferimenti nel codice.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.