Reference one string from another string in strings.xml?
Solution 1
A nice way to insert a frequently used string (e.g. app name) in xml without using Java code: 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>
UPDATE:
You can even define your entity globaly e.g:
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>
Solution 2
It is possible to reference one within another as long as your entire string consists of the reference name. For example this will work:
<string name="app_name">My App</string>
<string name="activity_title">@string/app_name</string>
<string name="message_title">@string/app_name</string>
It is even more useful for setting default values:
<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>
Now you can use string_default
everywhere in your code and you can easily change the default at any time.
Solution 3
I think you can't. But you can "format" a string as you like:
<?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>
In the code:
Resources res = getResources();
String text = String.format(res.getString(R.string.message_text),
res.getString(R.string.button_text));
Solution 4
In Android you can't concatenate Strings inside xml
Following is not supported
<string name="string_default">@string/string1 TEST</string>
Check this link below to know how to achieve it
How to concatenate multiple strings in android XML?
Solution 5
I created simple gradle plugin which allows you to refer one string from another. You can refer strings which are defined in another file, for example in different build variant or library. Cons of this approach - IDE refactor won't find such references.
Use {{string_name}}
syntax to refer a string:
<?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>
To integrate the plugin, just add next code into you app or library module level build.gradle
file
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"
UPDATE: The library doesn't work with Android gradle plugin version 3.0 and above because the new version of the plugin uses aapt2 which packs resources into .flat binary format, so packed resources are unavailable for the library. As a temporary solution you can disable aapt2 by setting android.enableAapt2=false in your gradle.properties file.
Related videos on Youtube
Comments
-
dbm over 4 years
I would like to reference a string from another string in my strings.xml file, like below (specifically note the end of the "message_text" string content):
<?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>
I've tried the above syntax but then the text prints out the "@string/button_text" as clear text. Not what I want. I would like the message text to print "You don't have any items yet! Add one by pressing the 'Add item' button."
Is there any known way to achieve what I want?
RATIONALE:
My application has a list of items, but when that list is empty I show a "@android:id/empty" TextView instead. The text in that TextView is to inform the user how to add a new item. I would like to make my layout fool-proof to changes (yes, I'm the fool in question :-)-
mpkuth over 7 yearsThis answer to another similar question worked for me. No java necessary, but it only works within the same resource file.
-
-
dbm over 13 yearsI was actually hoping for a "non-logic" solution. Nevertheless a fair enough answer (and a the sheer speed of it grants you a green check mark :-)
-
Andrey Novikov over 13 years
String text = res.getString(R.string.message_text, res.getString(R.string.button_text));
is a little bit cleaner. -
Stephen Hosking over 11 yearsWhich also answers the question: how do I refer to the app_name string in an activity title. :)
-
sschuberth over 11 yearsThis should not read "as long as you reference the entire string" (which you always to by definition) but "as long as the referring string resource only consists of the reference name".
-
dbm about 11 yearsWell, funny story: that's my answer to a similar question you're referencing :-)
-
Eric Woodruff over 10 yearsThis is not really a reference, this is just an alias, which doesn't solve the problem of composing strings.
-
Eric Woodruff over 10 yearsThis is the closest thing to an answer on this question. I think we need to look into hooking into the layout xml parsing.
-
Admin over 8 yearsIs there a way to achieve this?
-
Mauro Panzeri over 7 yearsthis is the correct answer to the OP. This solution has other great benefits: (1) you can define the DTD in an external file and references it from any resource file to apply the substitution everywhere in your resources. (2) android studio let you rename/references/refactor the defined entities. Though , it does not autocomplete names while writing. (androidstudio 2.2.2)
-
usernotnull over 7 years@MauroPanzeri can you plz provide examples?
-
Mauro Panzeri over 7 years@RJFares You can go 2 ways: (a) "including" a whole entity file EG: look at this answer. OR (b): including every single entity defined in an external DTD as shown here. Note that neither one is perfect because with (a) you will loose the "refactoring" cabilities and (b) is very verbose
-
jpage4500 about 7 yearsI like this idea.. but it fails for me with this error:
> Could not get unknown property 'referencedString'
-
mr5 about 7 yearsDoes this technique works with translators? Especially, the one that offered by Google? I'm getting an error in Android Studio as of v2.2.3 when using this
-
zyamys almost 7 yearsCareful if you use this in a Android Library Project - you cannot overwrite it in your app.
-
Ghedeon almost 7 years@MauroPanzeri didn't manage to reference external entity file. Do you mind to post an example? Thanks.
-
Mauro Panzeri almost 7 years@Ghedeon: for a working example look here you just need to pay attention to the relative paths. but you'll lose the refactoring ability and i've not checked what happens with androidstudio's GUI for translations.
-
Alvaro Gutierrez Perez almost 7 years@MauroPanzeri gradle gives an error when using the SYSTEM keyword to reference a external entity, so i think they are not supported on android xml files. The error is (in spanish, sorry):
Error:(1, 3) Error: El contenido de los elementos debe constar de marcadores o datos de carácter con un formato correcto.
-
Alvaro Gutierrez Perez almost 7 yearsOk, I managed to get it working with external entities references, using a mix of both methods that @MauroPanzeri wrote about in his comment. This is the way I got it working:
<!DOCTYPE resources [ <!ENTITY % app_name SYSTEM "xml/resources/entities.dtd"> %app_name; ]>
(sorry, line feeds not allowed here). Refactor ability is still maintained but only on the same file, the declaration of the entity in the external file is not recognized when refactoring. The path must be relative to the project root for gradle to take it (in the editor you will get a file not found error). -
Snicolas over 6 yearsThis breaks with aapt2
-
Joseph Garrone over 6 yearsA example based on this answer of referencing external entities: stackoverflow.com/a/46017525/3731798
-
display name over 6 yearshas anyone been able to make it work with Android Plugin for Gradle 3.0.0 and Gradle 4.1 or later? I was working on Migrating my Android project and that suddenly stopped working? The error I get is 'The Entity 'something' was referenced, but not declared'
-
Zam Sunk over 6 yearsThis is litterally useless, I can't think of any case where this can be useful. Just reference the actual string instead of the "alias"
-
intrepidis over 6 yearsThis doesn't answer the question, they wanted one string embedded in another.
-
Myoch over 6 yearsis it possible to change the entity value when defining flavors in the gradle file?
-
vineeth over 6 years@JamesBond where you able to find any solution to make this work with Android Plugin for Gradle 3.0.0 and Gradle 4.1. If not, do you have any other suggestions?. I am still facing the same error - The Entity 'something' was referenced, but not declared' during migration. I had to copy all entities in all strings.xml to make it work.
-
Sarath Kn about 6 yearseven I'm getting the same error
something' was referenced, but not declared
. Anyone found any solution? -
maudem almost 6 yearsSame problem : The entity "appname" was referenced, but not declared.
-
Davide Cannizzo over 5 yearsExternal entities are not supported by Android Studio anymore, since a bug discussed here: stackoverflow.com/a/51330953/8154765
-
CoolMind over 5 yearsIt is a duplicate of @Francesco Laurita answer, how to programmatically replace a string.
-
CoolMind over 5 yearsNow you have 53.
-
CoolMind over 5 yearsYou copy other solutions. When reference several strings, use
%1$s
,%2$s
, etc. instead of%s
. -
Ismail Iqbal over 5 years@CoolMind can you mention the reference to the copy.
-
TheRealChx101 about 5 yearsHow about referencing integers from within a string? For instance, in integers.xml,
<integer name="min_len">30</integer>
. And in strings.xml,<string name="placeholder">Your message needs to be at least @integer/min_len long</string>
. I do not want to hard code this value because I know I will change it in the future. -
César Muñoz over 4 yearsI've created a plugin that does pretty much the same and works with aapt2: github.com/LikeTheSalad/android-string-reference :)
-
Vadiraj Purohit over 4 yearsI tried your library. After following the steps you have given. It keeps giving build errors. Your library doesn't work at all
-
César Muñoz over 4 yearsI see, sorry to hear that. If you like, please create an issue here: github.com/LikeTheSalad/android-string-reference/issues with the logs and I can address it asap in case that it's a feature problem, or if it's a configuration issue I can also help you there. 👍
-
Jeff Padgett about 4 yearsThis causes a org.xml.sax.SAXException: Scanner State 24 not Recognized for me, Android Studio 3.6.1
-
ban-geoengineering about 4 yearsDoes anyone know if/how it's possible to get our custom entities recognised in a
<![CDATA[ ... ]]>
string resource? -
MahNas92 almost 3 yearsWhat if app_name looked somethin link <string name="app_name">My App %s$1</string> Can I reference to it and also pass a stringvalue to substitute %s$1 with? (Programatically similar to getString(R.String.app_name, "replacement");)
-
lenooh over 2 yearsThis seems like the cleanest solution. Everything else is messy.