Hacer referencia a una cadena en un recurso de matriz de cadenas con xml

256

Tengo preferencias donde puede habilitar / deshabilitar qué elementos aparecerán en el menú. Hay 17 artículos. Hice una matriz de cadenas en values ​​/ arrays.xml con títulos para cada uno de estos 17 elementos.

Tengo preferencias.xml que tiene el diseño para mi archivo de preferencias, y me gustaría hacer referencia a un solo elemento de la matriz de cadenas para usar como título.

¿Cómo puedo hacer esto?

En la referencia del desarrollador de Android, veo cómo puedo hacer referencia a una sola cadena con XML, pero no cómo puedo hacer referencia a una cadena desde un recurso de matriz en XML.

Jorsher
fuente

Respuestas:

331

En resumen: No creo que se puede, pero no parece haber una solución: .

Si echa un vistazo a los recursos de Android aquí:

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

Verá que en la sección de matriz (matriz de cadena, al menos), la "REFERENCIA DE RECURSOS" (como se obtiene de un XML) no especifica una forma de abordar los elementos individuales. Incluso puede intentar en su XML usar "@ array / yourarrayhere". Sé que en tiempo de diseño obtendrás el primer artículo. Pero eso no tiene ningún uso práctico si quieres usar, digamos ... el segundo, por supuesto.

SIN EMBARGO, hay un truco que puedes hacer. Mira aquí:

Hacer referencia a una cadena XML en una matriz XML (Android)

Puede "engañar" (no realmente) la definición de matriz al direccionar cadenas independientes DENTRO de la definición de la matriz. Por ejemplo, en su 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>

Al usar esto, puede usar "@ string / earth" y "@ string / moon" normalmente en sus campos XML "android: text" y "android: title", y aún así no perderá la capacidad de usar la matriz definición para cualquier propósito que pretendía en primer lugar.

Parece trabajar aquí en mi Eclipse. ¿Por qué no intentas decirnos si funciona? :-)

davidcsb
fuente
32
si solo pudiéramos darle nameetiquetas a <item> s ... * suspiro *
Algún estudiante de Noob
2
¡Solo lo intenté! Definió la matriz en el valor predeterminado strings.xmlpero no lo hizo values-fry la matriz aún se actualizó con la versión en francés. Muy mal ... pero genial, ¡funciona!
Blundell
1
Consejo rápido para cualquier persona: hacer doble clic en "tierra" resaltará la tierra. Hacer doble clic en la luna en @ string / moon resaltará solo moon. Por lo tanto, si duplica el primer elemento varias veces al crear su matriz, puede copiar y pegar entre sus cadenas individuales y la matriz de cadenas con bastante facilidad. Podría ayudar a acelerar la creación de su conjunto de cadenas :)
ArtOfWarfare
2
¿Solo quiero saber si este enfoque causa un peor rendimiento que si declaro las cadenas en la matriz tal como están pero sin usar referencias?
Alex Bonel
1
@AlexBonel una pregunta interesante, y sinceramente no lo sé. Incluso si así fuera, creo que deberíamos dejar este tipo de micro optimización para el compilador. De todos modos, ¿no terminan en línea en algún lugar del camino? Supongo que sí, pero no estoy seguro. Al menos en un nivel superior en la cadena de Android, sé que puede desmontar completamente un APK con apktool, y recuperará los nombres originales de las teclas de cadena, lo que significa que se mantienen las declaraciones referenciadas, como la anterior. Pero no estoy muy interesado en esa área en este momento, así que no puedo responder a su pregunta. Sin embargo, es una buena pregunta.
davidcsb
217

Quizás esto ayude:

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

Entonces obtienes el array-list como String [] y luego eliges cualquier i, some_array [i].


fuente
10
Entiendo cómo obtener el recurso de matriz. Sin embargo, eso no me permite hacer referencia al elemento de la matriz en un diseño xml.
Jorsher
1
Oh, lo siento. Entendí mal. Bueno, ¿tiene que estar en el diseño xml? Si el título cambia con la elección del usuario, ¿por qué no hacerlo en el archivo .java? Por ejemplo .setText (some_array [i]).
2
Porque, el diseño de preferencias está en xml. Java carga el menú con los elementos que están "habilitados" en las preferencias. Escribir 17 verificaciones de preferencias, y el código subsiguiente para agregarlo a la vista de lista me parece redundante y descuidado.
Jorsher
Esto fue útil cuando estaba creando un adaptador de matriz a partir de una matriz xml en mi carpeta de valores
EHarpham
Encontré esto útil cuando necesito un valor predeterminado al obtener una preferencia: String myPref = preferences.getString(context.getResources().getString(R.string.my_pref), some_array [0]);donde my_pref se configuró previamente en algún valor some_array [x]
Al Lelopath
67

La mejor opción sería simplemente usar la matriz de recursos devueltos como una matriz, lo que significa:

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

Este es un enfoque de acceso directo de los enfoques mencionados anteriormente, pero hace el trabajo de la manera que desea. De lo contrario, Android no proporciona indexación XML directa para matrices basadas en XML.

Amitesh
fuente
1
@ Benjiko99 gracias por detectar el error, lo he cambiado en consecuencia.
Amitesh
Esta es la forma más concisa de hacerlo. +1!
suomi35
1
Esto puede parecer más conciso, pero si alguien o el traductor cambia el orden de la matriz en el archivo de cadenas, terminará usando la cadena incorrecta.
nuevoDeveloper
9

Desafortunadamente:

  • Parece que no puede hacer referencia a un solo elemento de una matriz en values ​​/ arrays.xml con XML. Por supuesto que puedes en Java, pero no en XML. No hay información sobre cómo hacerlo en la referencia del desarrollador de Android, y no pude encontrar ninguna en ningún otro lado.

  • Parece que no puede usar una matriz como clave en el diseño de preferencias. Cada clave tiene que ser un valor único con su propio nombre de clave.

Lo que quiero lograr: quiero poder recorrer las 17 preferencias, verificar si el elemento está marcado y, si es así, cargar la cadena de la matriz de cadenas para ese nombre de preferencia.

Aquí está el código que esperaba completaría esta tarea:

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

Lo que hice:

  • Establecí una sola cadena para cada uno de los elementos, y hice referencia a las cadenas individuales en el. Utilizo la referencia de cadena única para los títulos de las casillas de verificación de diseño de preferencias y la matriz para mi bucle.

  • Para recorrer las preferencias, acabo de nombrar las claves como clave1, clave2, clave3, etc. Dado que hace referencia a una clave con una cadena, tiene la opción de "construir" el nombre de la clave en tiempo de ejecución.

Aquí está el nuevo código:

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

Otra forma de hacerlo es definir una matriz de recursos en strings.xml como a continuación.

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

y luego definiendo un conjunto de cadenas usando los recursos anteriores

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

También puede referir la misma cadena a otros xmls manteniendo DRY intacto. La ventaja que veo es que con un solo cambio de valor afectaría todas las referencias en el código.

Amruta-Pani
fuente