uso texto studio strings resource recurso poner paramétros mensaje manejo español cómo como arreglo array archivo android xml string

android - texto - strings.xml español



¿Hace referencia a una cadena de otra cadena en strings.xml? (10)

Me gustaría hacer referencia a una cadena de otra cadena en mi archivo strings.xml, como a continuación (específicamente observe el final del contenido de la cadena "message_text"):

<?xml version="1.0" encoding="utf-8"?> <resources> <string name="button_text">Add item</string> <string name="message_text">You don''t have any items yet! Add one by pressing the /'@string/button_text/' button.</string> </resources>

Probé la sintaxis anterior, pero luego el texto imprime "@ string / button_text" como texto claro. No es lo que quiero Me gustaría que se imprima el texto del mensaje "¡Aún no tiene ningún elemento! Agregue uno presionando el botón ''Agregar elemento''".

¿Hay alguna manera conocida de lograr lo que quiero?

RAZÓN FUNDAMENTAL:
Mi aplicación tiene una lista de elementos, pero cuando esa lista está vacía, muestro una "@android: id / empty" TextView en su lugar. El texto en ese TextView es para informar al usuario cómo agregar un nuevo elemento. Me gustaría hacer mi diseño a prueba de cambios (sí, soy el tonto en cuestión :-)


Además de la respuesta anterior de Francesco Laurita https://.com/a/39870268/9400836

Parece que hay un error de compilación "& entity; se hizo referencia, pero no se declaró", que se puede resolver haciendo referencia a la declaración externa como esta

res / raw / entities.ent

<!ENTITY appname "My App Name">

res / values ​​/ strings.xml

<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE resources [ <!ENTITY appname SYSTEM "/raw/entities.ent"> ]> <resources> <string name="app_name">&appname;</string> </resources

Aunque compila y ejecuta, tiene un valor vacío. Quizás alguien sepa cómo resolver esto. Hubiera publicado un comentario pero la reputación mínima es 50.


Con el nuevo enlace de datos puede concatenar y hacer mucho más en su xml.

por ejemplo, si tienes message1 y message2 puedes:

android:text="@{@string/message1 + '': '' + @string/message2}"

incluso puede importar algunas utilidades de texto y llamar a String.format y sus amigos.

Desafortunadamente, si quiere reutilizarlo en varios lugares puede ser complicado, no quiere que este código se rompa en todas partes. y no puedes definirlos en xml en un solo lugar (no que yo sepa) así que para eso puedes crear una clase que encapsule esas composiciones:

public final class StringCompositions { public static final String completeMessage = getString(R.string.message1) + ": " + getString(R.string.message2); }

luego puede usarlo en su lugar (deberá importar la clase con enlace de datos)

android:text="@{StringCompositions.completeMessage}"


Creé un plugin gradle simple que le permite referir una cadena de otra. Puede referir cadenas que están definidas en otro archivo, por ejemplo, en una variante de compilación o biblioteca diferente. En contra de este enfoque, IDE refactor no encontrará tales referencias.

Use la sintaxis de {{string_name}} para referir una cadena:

<?xml version="1.0" encoding="utf-8"?> <resources> <string name="super">Super</string> <string name="app_name">My {{super}} App</string> <string name="app_description">Name of my application is: {{app_name}}</string> </resources>

Para integrar el complemento, simplemente agregue el siguiente código en su aplicación o archivo de nivel de biblioteca build.gradle

buildscript { repositories { maven { url "https://plugins.gradle.org/m2/" } } dependencies { classpath "gradle.plugin.android-text-resolver:buildSrc:1.2.0" } } apply plugin: "com.icesmith.androidtextresolver"

ACTUALIZACIÓN: La biblioteca no funciona con Android Gradle Plugin versión 3.0 y superior porque la nueva versión del complemento utiliza aapt2, que empaqueta recursos en formato binario .flat, por lo que los recursos empaquetados no están disponibles para la biblioteca. Como solución temporal, puede desactivar aapt2 configurando android.enableAapt2 = false en su archivo gradle.properties.


Creo que no puedes. Pero puede "formatear" una cadena como desee:

<?xml version="1.0" encoding="utf-8"?> <resources> <string name="button_text">Add item</string> <string name="message_text">You don''t have any items yet! Add one by pressing the %1$s button.</string> </resources>

En el código:

Resources res = getResources(); String text = String.format(res.getString(R.string.message_text), res.getString(R.string.button_text));


En Android no puedes concatenar cadenas dentro de xml

Lo siguiente no es compatible

<string name="string_default">@string/string1 TEST</string>

Consulte este enlace a continuación para saber cómo lograrlo

Cómo concatenar múltiples cadenas en Android XML?


Es posible hacer referencia a uno dentro de otro siempre que toda la cadena consista en el nombre de referencia. Por ejemplo, esto funcionará:

<string name="app_name">My App</string> <string name="activity_title">@string/app_name</string> <string name="message_title">@string/app_name</string>

Es aún más útil para establecer valores predeterminados:

<string name="string1">String 1</string> <string name="string2">String 2</string> <string name="string3">String 3</string> <string name="string_default">@string/string1</string>

Ahora puede usar string_default en todas partes en su código y puede cambiar fácilmente el valor predeterminado en cualquier momento.


Puede usar marcadores de posición de cadena (% s) y reemplazarlos usando java en tiempo de ejecución

<resources> <string name="button_text">Add item</string> <string name="message_text">Custom text %s </string> </resources>

y en java

String final = String.format(getString(R.string.message_text),getString(R.string.button_text));

y luego establecerlo en el lugar donde usa la cadena


Puede usar su propia lógica, que resuelve las cadenas anidadas recursivamente.

/** * Regex that matches a resource string such as <code>@string/a-b_c1</code>. */ private static final String REGEX_RESOURCE_STRING = "@string/([A-Za-z0-9-_]*)"; /** Name of the resource type "string" as in <code>@string/...</code> */ private static final String DEF_TYPE_STRING = "string"; /** * Recursively replaces resources such as <code>@string/abc</code> with * their localized values from the app''s resource strings (e.g. * <code>strings.xml</code>) within a <code>source</code> string. * * Also works recursively, that is, when a resource contains another * resource that contains another resource, etc. * * @param source * @return <code>source</code> with replaced resources (if they exist) */ public static String replaceResourceStrings(Context context, String source) { // Recursively resolve strings Pattern p = Pattern.compile(REGEX_RESOURCE_STRING); Matcher m = p.matcher(source); StringBuffer sb = new StringBuffer(); while (m.find()) { String stringFromResources = getStringByName(context, m.group(1)); if (stringFromResources == null) { Log.w(Constants.LOG, "No String resource found for ID /"" + m.group(1) + "/" while inserting resources"); /* * No need to try to load from defaults, android is trying that * for us. If we''re here, the resource does not exist. Just * return its ID. */ stringFromResources = m.group(1); } m.appendReplacement(sb, // Recurse replaceResourceStrings(context, stringFromResources)); } m.appendTail(sb); return sb.toString(); } /** * Returns the string value of a string resource (e.g. defined in * <code>values.xml</code>). * * @param name * @return the value of the string resource or <code>null</code> if no * resource found for id */ public static String getStringByName(Context context, String name) { int resourceId = getResourceId(context, DEF_TYPE_STRING, name); if (resourceId != 0) { return context.getString(resourceId); } else { return null; } } /** * Finds the numeric id of a string resource (e.g. defined in * <code>values.xml</code>). * * @param defType * Optional default resource type to find, if "type/" is not * included in the name. Can be null to require an explicit type. * * @param name * the name of the desired resource * @return the associated resource identifier. Returns 0 if no such resource * was found. (0 is not a valid resource ID.) */ private static int getResourceId(Context context, String defType, String name) { return context.getResources().getIdentifier(name, defType, context.getPackageName()); }

De una Activity , por ejemplo, llámalo así

replaceResourceStrings(this, getString(R.string.message_text));


Soy consciente de que esta es una publicación más antigua, pero quería compartir la solución rápida y sucia que he creado para un proyecto mío. Solo funciona para TextViews, pero también se puede adaptar a otros widgets. Tenga en cuenta que requiere que el enlace se incluya entre corchetes (por ejemplo, [@string/foo] ).

public class RefResolvingTextView extends TextView { // ... @Override public void setText(CharSequence text, BufferType type) { final StringBuilder sb = new StringBuilder(text); final String defPackage = getContext().getApplicationContext(). getPackageName(); int beg; while((beg = sb.indexOf("[@string/")) != -1) { int end = sb.indexOf("]", beg); String name = sb.substring(beg + 2, end); int resId = getResources().getIdentifier(name, null, defPackage); if(resId == 0) { throw new IllegalArgumentException( "Failed to resolve link to @" + name); } sb.replace(beg, end + 1, getContext().getString(resId)); } super.setText(sb, type); } }

La desventaja de este enfoque es que setText() convierte CharSequence en una String , lo cual es un problema si pasas cosas como SpannableString ; para mi proyecto esto no fue un problema ya que solo lo TextViews para TextViews que no tuve que acceder desde mi Activity .


Una buena manera de insertar una cadena de uso frecuente (por ejemplo, el nombre de la aplicación) en xml sin usar código Java: source

<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE resources [ <!ENTITY appname "MyAppName"> <!ENTITY author "MrGreen"> ]> <resources> <string name="app_name">&appname;</string> <string name="description">The &appname; app was created by &author;</string> </resources>

ACTUALIZAR:

Incluso puede definir su entidad globaly por ejemplo:

res / raw / entities.ent:

<!ENTITY appname "MyAppName"> <!ENTITY author "MrGreen">

res / values ​​/ string.xml:

<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE resources [ <!ENTITY % ents SYSTEM "./res/raw/entities.ent"> %ents; ]> <resources> <string name="app_name">&appname;</string> <string name="description">The &appname; app was created by &author;</string> </resources>