Reputation: 2361
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.
Upvotes: 210
Views: 112522
Reputation: 586
if you search one way to set your text with DataBinding when you have a string.xml like that
strings.xml
<string name="your_string_name"><![CDATA[<b>Name: </b>%s]]</string>
this @BindingAdapter can help you
BindingAdapters.kt
@BindingAdapter("spannedText")
fun TextView.setSpannedTextAdapter(formated: String) {
text = HtmlCompat.fromHtml(formated, HtmlCompat.FROM_HTML_MODE_LEGACY)
}
TextView atribute in your XML layout
app:spannedText="@{@string/your_string_name(`Hello World!`)}"
Output
Name: Hello World!
Upvotes: 1
Reputation: 421
yourViewBinding.yourTextView.setText(this.yourViewBinding.getRoot().getResources().getString(R.string.your_string) + yourStringVariable);
Upvotes: 0
Reputation: 398
strings.xml: <string name="my_string">Hello %s</string>
view.xml: android:text="@{@string/my_string(name)}"
Upvotes: 12
Reputation: 606
just put or append your string resource name it will work fine
e.x @string/test
android:text="@{@string/test+viewModel.name+@string/test}"
Upvotes: 0
Reputation: 2179
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.
Upvotes: 5
Reputation: 9267
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.
Upvotes: 8
Reputation: 4039
Just using +
operator works for me:
android:text= "@{@string/Generic_Text +' '+ Profile.name)}"
String.xml will be:
<string name="Generic_Text">Hello</string>
Upvotes: 2
Reputation: 283
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`)}"
Upvotes: 7
Reputation: 816
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}"
Upvotes: 9
Reputation: 58984
android:text= "@{@string/generic_name(user.name)}"
Just make string resource like this.
<string name="generic_name">Hello %s</string>
android:text="@{`Hello ` + user.name}"/>
This is useful when you need hardcoded append like + for phone number.
String
's concat methodandroid: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>
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>
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.
Upvotes: 94
Reputation: 4730
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:
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>
It works just because it's designed in data binding. More in docs: https://developer.android.com/topic/libraries/data-binding/expressions#resources
Upvotes: 436
Reputation: 5421
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.
Upvotes: 1
Reputation: 8680
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
Upvotes: 238