Referenciando uma string em um recurso de matriz de string com xml

256

Tenho preferências nas quais você pode ativar / desativar quais itens serão exibidos no menu. Existem 17 itens. Eu fiz uma matriz de string em values ​​/ arrays.xml com títulos para cada um desses 17 itens.

Eu tenho o arquivo lists.xml, que possui o layout do meu arquivo de preferências, e gostaria de referenciar um único item da matriz de strings para usar como título.

Como posso fazer isso?

Na referência do desenvolvedor do Android, vejo como posso referenciar uma única string com XML, mas não como posso referenciar uma string de um recurso de matriz em XML.

Jorsher
fonte

Respostas:

331

Em suma: eu não acho que você pode, mas parece haver uma solução alternativa: .

Se você der uma olhada no recurso Android aqui:

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

Você vê que, na seção matriz (matriz de cadeias, pelo menos), a "REFERÊNCIA DE RECURSOS" (como você obtém de um XML) não especifica uma maneira de abordar os itens individuais. Você pode até tentar no seu XML usar "@ array / yourarrayhere". Eu sei que em tempo de design, você receberá o primeiro item. Mas isso não tem utilidade prática se você quiser usar, digamos ... o segundo, é claro.

No entanto, há um truque que você pode fazer. Veja aqui:

Referenciando uma string XML em uma matriz XML (Android)

Você pode "enganar" (não realmente) a definição da matriz, abordando cadeias independentes DENTRO da definição da matriz. Por exemplo, no seu 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>

Ao usar isso, você pode usar "@ string / earth" e "@ string / moon" normalmente nos campos XML "android: text" e "android: title" e, no entanto, não perderá a capacidade de usar a matriz definição para quaisquer fins que você pretendeu em primeiro lugar.

Parece funcionar aqui no meu Eclipse. Por que você não tenta nos dizer se funciona? :-)

davidcsb
fonte
32
se pudéssemos apenas dar nametags para <item> s ... * sigh *
Some Student Noob
2
Apenas tentei! Definiu a matriz no padrão, strings.xmlmas não entrou values-fre a matriz ainda é atualizada com a versão em francês. Tão errado .. mas legal funciona!
Blundell
1
Dica rápida para qualquer pessoa: clicar duas vezes em "terra" destacará a terra. Clicar duas vezes na lua em @ string / moon destacará apenas a lua. Portanto, se você duplicar o primeiro item várias vezes ao criar sua matriz, poderá copiar e colar entre suas seqüências individuais e a matriz com bastante facilidade. Pode ajudar com a aceleração da criação de sua corda-array :)
ArtOfWarfare
2
Só quero saber se essa abordagem causa desempenho pior do que se eu declarar seqüências de caracteres na matriz como elas estão, mas não usando referências?
Alex Bonel
1
@AlexBonel é uma pergunta interessante, e sinceramente não sei. Mesmo assim, acho que devemos deixar esse tipo de micro otimização para o compilador. Enfim, eles não terminam alinhados em algum lugar na estrada? Eu acho que sim, mas não tenho certeza. Pelo menos em um nível superior na cadeia do Android, eu sei que você pode desmontar completamente um APK com apktool, e ele recuperará os nomes originais das chaves da string, o que significa que as declarações referenciadas, como a acima, são mantidas. Mas não estou muito interessado nessa área no momento, então não posso responder sua pergunta. É uma boa pergunta, no entanto.
Davidcsb
216

Talvez isso ajude:

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

Então você obtém a lista de matrizes como uma String [] e, em seguida, escolhe qualquer i, some_array [i].


fonte
10
Eu entendo como obter o recurso de matriz. Isso não me permite referenciar o item da matriz em um layout xml.
Jorsher
1
Ah desculpa. Eu entendi errado. Bem, ele precisa estar no layout xml? Se o título mudar com a escolha do usuário, por que não fazê-lo no arquivo .java. Por exemplo, .setText (some_array [i]).
2
Porque, o layout de preferências está em xml. O java carrega o menu com os itens "ativados" nas preferências. Digitar 17 checagens de preferências e o código subseqüente para adicioná-lo à listview parece redundante e desleixado para mim.
Jorsher
Este foi útil quando eu estava criando um ArrayAdapter de uma matriz xml em meus valores pasta
EHarpham
Eu encontrei este útil quando precisar de um valor padrão quando chegar uma preferência: String myPref = preferences.getString(context.getResources().getString(R.string.my_pref), some_array [0]);onde my_pref foi previamente definida para algum valor some_array [x]
Al Lelopath
67

A melhor opção seria usar apenas o recurso retornado como uma matriz, o que significa:

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

Essa é uma abordagem de atalho das abordagens mencionadas acima, mas funciona da maneira que você deseja. Caso contrário, o Android não fornece indexação XML direta para matrizes baseadas em xml.

Amitesh
fonte
1
@ Benjiko99 obrigado por detectar o erro, alterou-o de acordo.
Amitesh
Essa é a maneira mais concisa de fazer isso. +1!
amigos estão dizendo sobre suomi
1
isso pode parecer mais conciso, mas se alguém ou o tradutor alterar a ordem da matriz no arquivo de strings, você acabará usando a string errada.
newDeveloper 2/11/16
9

Infelizmente:

  • Parece que você não pode fazer referência a um único item de uma matriz em values ​​/ arrays.xml com XML. Claro que você pode em Java, mas não XML. Não há informações sobre como fazê-lo na referência de desenvolvedor do Android e não consegui encontrar nenhum outro lugar.

  • Parece que você não pode usar uma matriz como uma chave no layout de preferências. Cada chave deve ter um valor único com seu próprio nome de chave.

O que quero realizar: desejo poder percorrer as 17 preferências, verificar se o item está marcado e, se estiver, carregar a string da matriz de strings para esse nome de preferência.

Aqui está o código que eu esperava que concluísse esta tarefa:

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

O que eu fiz:

  • Eu defini uma única string para cada um dos itens e referenciei as strings únicas no. Eu uso a referência de cadeia única para os títulos das caixas de seleção de layout de preferências e a matriz para meu loop.

  • Para percorrer as preferências, acabei de nomear as teclas como chave1, chave2, chave3, etc. Como você faz referência a uma chave com uma string, você tem a opção de "construir" o nome da chave em tempo de execução.

Aqui está o novo código:

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

Outra maneira de fazer isso é definir uma matriz de recursos em strings.xml, como abaixo.

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

e, em seguida, definindo uma matriz de cadeias usando os recursos acima

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

Você também pode consultar a mesma string em outros xmls, mantendo o DRY intacto. A vantagem que vejo é que, com uma única alteração de valor, afetaria todas as referências no código.

Amruta-Pani
fonte