How do I use databinding to combine a string from resources with a dynamic variable in XML?

AndroidAndroid Databinding

Android Problem Overview


I have a TextView which has a hardcoded string and I have a dynamic variable that I want to put at the end of this string. This is my code:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp">
    <TextView
        android:id="@+id/PeopleName"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/Generic_Text"+"@{ Profile.name }" />


</LinearLayout>

I am having an issue with android:text="@string/Generic_Text"+"@{ Profile.name }" . The Generic_Text states " My Name is " then the Profile.name is dynamic and obviously changes from profile to profile. I want it so that the whole TextView output is My Name is {Profile.name}. Any help would be great.

Android Solutions


Solution 1 - Android

You can do this even simplier:

android:text= "@{@string/generic_text(profile.name)}"

you string should be like this:

<string name="generic_text">My Name is %s</string>

Edit:

  1. Of course you can use as many variables as you need:

     android:text= "@{@string/generic_text(profile.firstName, profile.secondName)}"
    
     <string name="generic_text">My Name is %1$s %2$s</string>
    
  2. It works just because it's designed in data binding. More in docs: https://developer.android.com/topic/libraries/data-binding/expressions#resources

Solution 2 - Android

You can do this:

android:text= "@{String.format(@string/Generic_Text, Profile.name)}"

if you use string formatting for your Generic_Text string. ex. %s at the end

Solution 3 - Android

Many ways to concat strings

android:text= "@{@string/generic_name(user.name)}"

Just make string resource like this.

<string name="generic_name">Hello %s</string>
2. Hard coded concat
android:text="@{`Hello ` + user.name}"/>

This is useful when you need hardcoded append like + for phone number.

3. Using String's concat method
android:text="@{user.firstName.concat(@string/space).concat(user.lastName)}"

Here space is an html entity which is placed inside strings.xml. Because XML does not accept Html entities or special characters directly. (Link Html Entities)

<string name="space">\u0020</string>
4. Using String.format()
android:text= "@{String.format(@string/Hello, user.name)}"

you have to import String class in layout in this type.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <import type="String" />
    </data>
    <TextView
        android:text= "@{String.format(@string/Hello, user.name)}"
        ... >
    </TextView>
</layout>
5. concat two strings by string resource.
android:text="@{@string/generic_name(user.firstName,user.lastName)}"

In this case put a string resource in strings.xml

<string name="generic_name">%1$s, %2$s</string>

There can be many other ways, choose one you need.

Solution 4 - Android

2019 Update, Android studio to 3.4, Android Gradle Plugin to 3.4

No more required to import

<import type="java.lang.String" />" 

for string operations. Please check this answer.

Solution 5 - Android

Use a Binding Adapter.

This sample is written in Kotlin and takes into account that the bound variable can be null:

@BindingAdapter("my_name")
fun TextView.setMyName(name: String?) {
    this.text =
        if (name.isNullOrEmpty()) "" else "${this.context.getString(R.string.Generic_Text)} $name"
}

then use the binding adapter in your XML instead of the android:text property

app:my_name="@{Profile.name}"

Solution 6 - Android

In case if you want to type text in XML, you can use `` quotation.

android:text="@{`Device Name`}"

elsewhere you need to Concat with the String or variable, you can use

android:text="@{`Device Name`.concat(android.os.Build.MANUFACTURER)}"

if you want to Concat string resource instead of the variable you can do,

android:text="@{@string/app_name.concat(`Device Name`)}"

Solution 7 - Android

You can also set string resource as parameter to other string resource using formatter like below:

<string name="first_param_text">Hello</string>
<string name="second_param_text">World</string>
<string name="formatted_text">%s lovely %s</string>

and

android:text="@{String.format(@string/formatted_text, @string/first_param_text, @string/second_param_text)}"

"Hello lovely World" will appear on the view.

Solution 8 - Android

strings.xml: <string name="my_string">Hello %s</string>

view.xml: android:text="@{@string/my_string(name)}"

Solution 9 - Android

Just using + operator works for me:

android:text= "@{@string/Generic_Text +' '+ Profile.name)}"

String.xml will be:

<string name="Generic_Text">Hello</string>

Solution 10 - Android

In case you can't change the resource string to contain %s at the end (eg. because it's used elsewhere without the suffix):

android:text="@{@string/Generic_Text.concat(Profile.name)}"

If Profile.name can't be null, that's enough. However, if a null happens, it'll crash. You have to add another layer:

android:text="@{@string/Generic_Text.concat(Objects.toString(Profile.name))}"

(which requires <import type="java.util.Objects"/> to work.)

Again: all this extra work is worth it only if you have the resource string used elsewhere. The second reason is when you want to handle null as "empty string" instead of a "null" literal.

Solution 11 - Android

just put or append your string resource name it will work fine

e.x @string/test

android:text="@{@string/test+viewModel.name+@string/test}"

Solution 12 - Android

yourViewBinding.yourTextView.setText(this.yourViewBinding.getRoot().getResources().getString(R.string.your_string) + yourStringVariable);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionIgnacio PerezView Question on Stackoverflow
Solution 1 - AndroidRoman_DView Answer on Stackoverflow
Solution 2 - AndroidC0D3LIC1OU5View Answer on Stackoverflow
Solution 3 - AndroidKhemraj SharmaView Answer on Stackoverflow
Solution 4 - AndroidSANATView Answer on Stackoverflow
Solution 5 - AndroidjuanaguiView Answer on Stackoverflow
Solution 6 - AndroidMerlin JeyakumarView Answer on Stackoverflow
Solution 7 - AndroidoguzhanView Answer on Stackoverflow
Solution 8 - AndroidA.Y.View Answer on Stackoverflow
Solution 9 - AndroidShalu T DView Answer on Stackoverflow
Solution 10 - AndroidAgent_LView Answer on Stackoverflow
Solution 11 - AndroidlemuriyanView Answer on Stackoverflow
Solution 12 - AndroidAshraf AminView Answer on Stackoverflow