programing tip

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

itbloger 2020. 8. 21. 07:24
반응형

데이터 바인딩을 사용하여 리소스의 문자열을 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상태는 다음이 "내 이름은" 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>

편집하다:

  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. 문자열 리소스 사용 ( 현지화로 인해 권장 됨 )

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>

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


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.


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.


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

참고URL : https://stackoverflow.com/questions/38978499/how-do-i-use-databinding-to-combine-a-string-from-resources-with-a-dynamic-varia

반응형