Ответ 1
Вы можете сделать это:
android:text= "@{String.format(@string/Generic_Text, Profile.name)}"
если вы используете форматирование строк для строки Generic_Text
. ех. %s
в конце
У меня есть TextView, у которого есть жестко закодированная строка, и у меня есть динамическая переменная, которую я хочу поставить в конце этой строки. Это мой код:
<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>
У меня проблема с android:text="@string/Generic_Text"+"@{ Profile.name }"
. В Generic_Text
указано "My Name is", тогда Profile.name
является динамическим и, очевидно, изменяется от профиля к профилю. Я хочу, чтобы весь вывод TextView был My Name is {Profile.name}. Любая помощь будет отличной.
Вы можете сделать это:
android:text= "@{String.format(@string/Generic_Text, Profile.name)}"
если вы используете форматирование строк для строки Generic_Text
. ех. %s
в конце
Вы можете сделать это еще проще:
android:text= "@{@string/generic_text(profile.name)}"
Ваша строка должна быть такой:
<string name="generic_text">My Name is %s</string>
Изменить:
Конечно, вы можете использовать столько переменных, сколько вам нужно:
android:text= "@{@string/generic_text(profile.firstName, profile.secondName)}"
<string name="generic_text">My Name is %1$s %2$s</string>
Он работает только потому, что он предназначен для привязки данных. Больше в документах: https://developer.android.com/topic/libraries/data-binding/expressions#resources
android:text= "@{@string/generic_name(user.name)}"
Просто сделайте строковый ресурс следующим образом.
<string name="generic_name">Hello %s</string>
android:text="@{'Hello ' + user.name}"/>
Это полезно, когда вам нужно жестко закодировать, например, + для номера телефона.
String
android:text="@{user.firstName.concat(@string/space).concat(user.lastName)}"
Здесь space
- это HTML-объект, который находится внутри strings.xml
. Потому что XML
не принимает Html-объекты или специальные символы напрямую. (Link Html Entities)
<string name="space">\u0020</string>
String.format()
android:text= "@{String.format(@string/Hello, user.name)}"
Вы должны импортировать класс String в макете в этом типе.
<?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)}"
В этом случае поместите строковый ресурс в strings.xml
<string name="generic_name">%1$s, %2$s</string>
Там может быть много других способов, выберите тот, который вам нужен.
Обновление 2019 года, Android-студия до 3.4, Android Gradle Plugin до 3.4
Больше не нужно импортировать
<import type="java.lang.String" />"
для строковых операций. Пожалуйста, проверьте этот ответ.
В случае, если вы не можете изменить строку ресурса, чтобы она содержала %s
в конце (например, потому что она использовалась в другом месте без суффикса):
android:text="@{@string/Generic_Text.concat(Profile.name)}"
Если Profile.name
не может быть нулевым, этого достаточно. Однако, если null
произойдет, он потерпит крах. Вы должны добавить еще один слой:
android:text="@{@string/Generic_Text.concat(Objects.toString(Profile.name))}"
(для работы которого требуется <import type="java.util.Objects"/>
.)
Опять же: вся эта дополнительная работа того стоит, только если у вас есть строка ресурса, используемая в другом месте. Вторая причина - когда вы хотите обрабатывать null
как "пустую строку" вместо "нулевого" литерала.
Используйте Binding Adapter.
Этот образец написан на Kotlin и учитывает, что связанная переменная может быть нулевой:
@BindingAdapter("my_name")
fun TextView.setMyName(name: String?) {
this.text =
if (name.isNullOrEmpty()) "" else "${this.context.getString(R.string.Generic_Text)} $name"
}
затем используйте адаптер привязки в своем XML вместо свойства android:text
app:my_name="@{Profile.name}"