데이터 바인딩을 사용하여 리소스의 문자열을 XML의 동적 변수와 결합하는 방법은 무엇입니까?


125

하드 코딩 된 문자열이있는 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상태는 다음이 "내 이름은" Profile.name동적이며 분명히 프로필 프로필에서 변경합니다. 전체 TextView 출력이 My Name is {Profile.name}이 되도록하고 싶습니다 . 어떤 도움이라도 좋을 것입니다.


데이터 바인딩을 사용하고 있습니까?
malmling

예, 저는 데이터 바인딩을 사용하고 있습니다
Ignacio Perez

현재 Java 코드도 추가하십시오.
malmling

답변:


162

다음과 같이 할 수 있습니다.

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

문자열에 문자열 형식을 사용하는 경우 Generic_Text. 전의. %s끝에


덕분에 많이 나는 그냥 그 넣어 올바르게 일
이그나시오 페레즈에게

5
이것은 실제로 텍스트를 조작하기 위해 데이터 바인딩 기능을 사용하지 않기 때문에 허용되는 대답이되어서는 안됩니다.
Darwind

1
참조하시기 바랍니다, @Darwind에 동의 내 대답을 어댑터 바인딩과 함께 작업 구현
juanagui

@IgorGanapolsky이 답변은 3 년이 넘었지만 이전에 확실히 사용 된 적이 있습니다. 시도했을 때 무엇이 ​​잘못되었는지 기억하십니까?
C0D3LIC1OU5

320

이 작업을 더 간단하게 수행 할 수 있습니다.

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


1
그러나 My Name is null데이터가 아직 준비되지 않은 경우 표시 됩니다 (예 : 네트워크에서로드되지 않았 음)
user924

1
이 경우에는 전에 확인하십시오. android:text= "@{profile == null ? @string/loading : @string/generic_text(profile.firstName, profile.secondName)}"
Roman_D

이것은 도움이됩니다!
akash89

최고의 답변 :)
Heriberto Rivera

55

문자열을 연결하는 다양한 방법

1. 문자열 리소스 사용 ( 현지화로 인해 권장 됨 )

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

이렇게 문자열 리소스를 만드십시오.

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

2. 하드 코딩 된 연결

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

전화 번호에 +와 같이 하드 코드 된 추가가 필요할 때 유용합니다.

3. String의 concat 메서드 사용

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

다음 space은 내부에 배치 된 html 엔티티입니다 strings.xml. 때문에 XML직접 HTML을 엔티티 또는 특수 문자를 허용하지 않습니다. (HTML 엔터티 연결)

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

다른 많은 방법이있을 수 있습니다. 필요한 것을 선택하십시오.


5

바인딩 어댑터를 사용하십시오 .

이 샘플은 Kotlin으로 작성되었으며 바인딩 된 변수가 null 일 수 있음을 고려합니다.

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

그런 다음 android:text속성 대신 XML에서 바인딩 어댑터를 사용하십시오.

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

바인딩에서 가져온 함수를 호출하는 데 많은 문제가 있었기 때문에이 답변은 저에게 완벽하게 작동하며 확장 기능을 재사용 할 수 있습니다. 감사!
Danny Buonocore

기본 조작은 이미 String클래스에서 제공하므로이 xml솔루션은 요구 사항에 따라 고급 문자열 조작에만 사용하는 것이 좋습니다. 그러나 그것은 정확하지 않습니다.
sud007

3

2019 업데이트, Android 스튜디오를 3.4로, Android Gradle 플러그인을 3.4로

더 이상 가져올 필요가 없습니다.

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

문자열 연산을 위해. 이 답변을 확인하십시오 .


1

끝에 포함 할 리소스 문자열을 변경할 수없는 경우 %s(예 : 접미사없이 다른 곳에서 사용되기 때문에) :

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

Profile.namenull이 될 수 없다면 충분합니다. 그러나 일이 null발생 하면 충돌합니다. 다른 레이어를 추가해야합니다.

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

( <import type="java.util.Objects"/>작동 해야 합니다.)

다시 말하지만,이 모든 추가 작업은 리소스 문자열이 다른 곳에서 사용되는 경우에만 가치가 있습니다. 두 번째 이유는 null"null"리터럴 대신 "빈 문자열" 로 처리하려는 경우 입니다.


2
문자열 리소스가 다른 곳에서 사용되는 경우 새 리소스를 만드는 것은 어떻습니까?
Jarett Millard

0

XML로 텍스트입력 하려는 경우 '' 인용문을 사용할 수 있습니다 .

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

다른 곳 에서 String 또는 변수와 연결 해야 할 경우 사용할 수 있습니다.

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

할 수있는 변수 대신 문자열 리소스연결 하려면

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

0

+연산자를 사용하는 것만으로도 효과가 있습니다.

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

String.xml은 다음과 같습니다.

<string name="Generic_Text">Hello</string>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.