Подтвердить что ты не робот

Как использовать привязку данных для объединения строки из ресурсов с динамической переменной в XML?

У меня есть 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}. Любая помощь будет отличной.

4b9b3361

Ответ 1

Вы можете сделать это:

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

если вы используете форматирование строк для строки Generic_Text. ех. %s в конце

Ответ 2

Вы можете сделать это еще проще:

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

Ваша строка должна быть такой:

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

Изменить:

  1. Конечно, вы можете использовать столько переменных, сколько вам нужно:

    android:text= "@{@string/generic_text(profile.firstName, profile.secondName)}"
    
    <string name="generic_text">My Name is %1$s %2$s</string>
    
  2. Он работает только потому, что он предназначен для привязки данных. Больше в документах: https://developer.android.com/topic/libraries/data-binding/expressions#resources

Ответ 3

Множество способов объединения строк

1. Использование строкового ресурса (Рекомендуется, поскольку локализация)

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

Просто сделайте строковый ресурс следующим образом.

<string name="generic_name">Hello %s</string>

2. Конкретный конкат

android:text="@{'Hello ' + user.name}"/>

Это полезно, когда вам нужно жестко закодировать, например, + для номера телефона.

3. Использование метода конкатов 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>

4. Использование 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>

5. конкатить две строки по строковому ресурсу.

android:text="@{@string/generic_name(user.firstName,user.lastName)}"

В этом случае поместите строковый ресурс в strings.xml

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

Там может быть много других способов, выберите тот, который вам нужен.

Ответ 4

Обновление 2019 года, Android-студия до 3.4, Android Gradle Plugin до 3.4

Больше не нужно импортировать

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

для строковых операций. Пожалуйста, проверьте этот ответ.

Ответ 5

В случае, если вы не можете изменить строку ресурса, чтобы она содержала %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 как "пустую строку" вместо "нулевого" литерала.

Ответ 6

Используйте 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}"