64

I go through this How to concatenate multiple strings in android XML? and in the end there are comments that

For clarity, Its works:

<string name="title">@string/app_name</string>.Andrzej Duś

I made my own example but it doesn't works. So does Andrzej wrong or I am doing something wrong in my code.

R.strings.bbb should contains "bbb aaa" but instead of "bbb aaa" it contains "bbb @strings/aaa"

<string name="aaa">aaa</string>
<string name="bbb">bbb @strings/aaa</string>

Query:

Is it possible to do some concatenation only in xml, without source code changes?

Reason why I don't want to edit in code because I use this strings in xml/preferences.xml

For Example:

<ListPreference android:key="key_bbb" android:title="@string/bbb" ....

If you know what I mean, here there is no possibility to use something like this

String title = res.getString(R.string.title, appName);
Community
  • 1
  • 1
Lukap
  • 31,523
  • 64
  • 157
  • 244
  • 1
    it seems no: http://stackoverflow.com/questions/8203540/how-can-i-concatenate-static-strings-with-xml-string-resources – Blackbelt May 02 '12 at 10:17
  • Not afaik - there's only support for a "single reference" - it does not concatenate two or more references (or text) into a single string, e.g. `@strings/aaa` should work whereas `test @strings/aaa` is interpreted as a raw string (as it does not start with a reference) - and `@strings/aaa @strings/aaa` would fail because it *would* be parsed as a *single* reference. The answer for his question was however to do it in code - and that works. – Jens May 02 '12 at 10:19

11 Answers11

80

No, you can't concatenate strings in XML but you can define XML resources.

<?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>

The original answer was posted here.

Community
  • 1
  • 1
Savelii Zagurskii
  • 997
  • 1
  • 9
  • 9
20

In XML only this is not possible but using the java code you can use the String.format() method.

<string name="aaa">aaa</string>
<string name="bbb">bbb %1$s</string>

In java code

String format = res.getString(R.string.bbb);
String title = String.format(format, res.getString(R.string.aaa));

So title will be a full string after concatenation of two strings.

Dharmendra
  • 33,296
  • 22
  • 86
  • 129
  • what do you suggest with my problem with xml preferences ? – Lukap May 02 '12 at 10:49
  • I know the answer is not related to XML preferences. Only xml can not handle the concat of two string it will give you compilation error as @MeAndWe had told you. I had give you the idea to concat two string using `String.format()` – Dharmendra May 02 '12 at 10:54
  • Wonder what is standard practice to append app names to the externalized strings in the app. This is very close though. :) – JaydeepW Feb 06 '15 at 12:38
15

No I don't think you can concatenate.

<string name="aaa">aaa</string>
<string name="bbb">bbb @string/aaa</string>

Output - bbb @string/aaa

If you do,

<string name="aaa">aaa</string>
<string name="bbb">@string/aaa bbb</string>  -> This won't work it
                                                      will give compilation error

Because here it will search for a String with reference @string/aaa bbb which does not exists.

Problem in your case was, you where using @strings/aaa which should be @string/aaa

Lalit Poptani
  • 67,150
  • 23
  • 161
  • 242
  • 3
    See Savelii Zagurskii's answer for a way to reuse a string multiple times in an xml file. – Andrew Nov 02 '15 at 02:22
9

You can concatenate the resources in gradle.build:

    resValue "string", "TWITTER_CALLBACK", "twitter_callback_" + applicationId
Boy
  • 7,010
  • 4
  • 54
  • 68
8

Yes, you can do it if your XML files are using DataBinding as you can see in this link

Use it like this:

"@{@string/first_string+ @string/second_string}"
batsheva
  • 2,175
  • 1
  • 20
  • 32
1

Kotlin version:

strings in the xml:

<string name="school_girl">Gogo Yubari</string>
<string name="assistant">Sofie Fatale</string>
<string name="boss">O-Ren Ishii</string>
<string name="list">%s, %s, %s</string>

and then in the code:

val killBillV1 = getString(R.string.list).format(
    Locale.US,
    getString(R.string.school_girl),
    getString(R.string.assistant),
    getString(R.string.boss)
)
netpork
  • 552
  • 7
  • 20
1

Yes, you can do so without having to add any Java/Kotlin code, just XML, by using this library: https://github.com/LikeTheSalad/android-stem which does that at buildtime.

For your case, you'd have to set up your strings like this:

<string name="aaa">Some text</string>
<string name="bbb">bbb ${aaa}</string>

And then the library will create the following at buildtime:

<!-- Auto generated during compilation -->
<string name="bbb">bbb Some text</string>

Disclaimer: I'm the author of this library.

César Muñoz
  • 535
  • 1
  • 6
  • 10
1

try like this if you want add multiple string value

                        <TextView
                        ..........
                        android:text='@{String.format("%s %s","+91", userInfo.mobile)}'
                        .............. />
Sandeep Pareek
  • 1,636
  • 19
  • 21
0

How about this technique

Use an array

<string name="app_link">https://myapp.com/</string>

<array name="update_dialog_msg">
    <item>Update can be downloaded manually by visiting this link:\n</item>
    <item>@string/app_link</item>
</array>

And then make a method in java class as below

public String getStringArray(int resStringArray)
{
    String str = "";

    String[] strArray = mContext.getResources().getStringArray(resStringArray);
    for (String s: strArray)
    {
        str += s;
    }

    return str;
}

Now call it from any java class as

mDialog.setMessage(getStringArray(R.array.update_dialog_msg);
// OR
textView.setText(getStringArray(R.array.update_dialog_msg);
0

Hi concat can do like this,

   android:text="@{userInfo.firstName.concat(@string/empty_str).concat(userInfo.lastName)}"
         

I guess its good sample for dynamic data. But if this sample containes other variation.Like User Name : Jon Doe

  android:text="@{String.format(@string/user_def,userInfo.firstName.concat(@string/empty_str).concat(userInfo.lastName))"
          

Thats it

Numan Turkeri
  • 526
  • 4
  • 18
-3

No, but is posible in xslt file with concat function:

<html>
      <body>
        <ul>
          <xsl:for-each select="stock">
            <xsl:if test="starts-with(@symbol, 'C')">
              <li>
                <xsl:value-of select="concat(@symbol,' - ', name)" />
              </li>
            </xsl:if>
          </xsl:for-each>
        </ul>
      </body>
    </html>

http://www.java2s.com/Tutorial/XML/0100__XSLT-stylesheet/concatfunction.htm

Ejrr1085
  • 975
  • 2
  • 16
  • 29