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 आउटपुट मेरा नाम {Profile.name} हो । कोई भी मदद बहुत अच्छी रहेगी।


क्या आप डेटाबाइंडिंग का उपयोग कर रहे हैं?
malmling

हां मैं डेटाबाइंडिंग का उपयोग कर रहा हूं
इग्नासियो पेरेज़

कृपया अपना वर्तमान जावा कोड जोड़ें।
malmling

जवाबों:


162

तुम यह केर सकते हो:

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

यदि आप अपने Generic_Textस्ट्रिंग के लिए स्ट्रिंग स्वरूपण का उपयोग करते हैं । पूर्व। %sअतं मै


बहुत बहुत धन्यवाद मैं बस डाल दिया और यह सही ढंग से काम किया
इग्नेसियो पेरेज

5
यह स्वीकृत उत्तर नहीं होना चाहिए, क्योंकि यह वास्तव में पाठ में हेरफेर करने के लिए डेटा बाइंडिंग सुविधाओं का उपयोग नहीं करता है।
डारविंड

1
@ डिअरविंड से सहमत, कृपया बाइंडिंग एडेप्टर के साथ काम करने के लिए मेरा जवाब देखें
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/lbooks/data-binding/expressions#resources


1
लेकिन यह दिखाता है My Name is nullकि डेटा अभी तैयार नहीं है (उदाहरण के लिए नेटवर्क से लोड नहीं किया गया था)
user924

1
इस मामले में पहले इसे जांचें। android:text= "@{profile == null ? @string/loading : @string/generic_text(profile.firstName, profile.secondName)}"
रोमन_ड

यह मददगार है!
अकाशॉ89

सबसे अच्छा जवाब :)
हर्बेर्टो रिवेरा

55

तार को समाप्‍त करने के कई तरीके

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सीधे एचटीएमएल संस्थाओं या विशेष पात्रों को स्वीकार नहीं करता है। (लिंक एचटीएमएल संस्थाओं)

<string name="space">\u0020</string>

4. उपयोग करना String.format()

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

आपको इस प्रकार के लेआउट में स्ट्रिंग वर्ग आयात करना होगा।

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

एक बंधन एडाप्टर का उपयोग करें ।

यह नमूना कोटलिन में लिखा गया है और यह ध्यान रखता है कि बाध्य चर शून्य हो सकता है:

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

बाइंडिंग में आयातित कार्यों को कॉल करने में बहुत परेशानी हो रही है, यह जवाब मेरे लिए पूरी तरह से काम करता है और मुझे अपने एक्सटेंशन का पुन: उपयोग करने की अनुमति देता है। धन्यवाद!
डैनी बुओनकोर

चूंकि, बुनियादी हेरफेर पहले से ही Stringवर्ग द्वारा प्रदान किया गया है xml, यह समाधान केवल अपनी आवश्यकताओं के आधार पर उन्नत स्ट्रिंग जोड़तोड़ के लिए उपयोग किया जाना अच्छा है। हालाँकि, यह गलत नहीं है।
सूद 7

3

2019 अपडेट, एंड्रॉइड स्टूडियो से 3.4, एंड्रॉइड ग्रैडल प्लगिन से 3.4

आयात करने के लिए और अधिक आवश्यक नहीं है

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

स्ट्रिंग ऑपरेशन के लिए। कृपया इस उत्तर की जाँच करें ।


1

यदि आप अंत में समाहित करने के लिए संसाधन स्ट्रिंग को नहीं बदल सकते हैं%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"शून्य" शाब्दिक के बजाय "खाली स्ट्रिंग" के रूप में संभालना चाहते हैं ।


2
यदि स्ट्रिंग संसाधन कहीं और उपयोग किया जाता है, तो बस एक नया संसाधन क्यों नहीं बनाया जाए?
जरीट मिलार्ड

0

यदि आप XML में टेक्स्ट लिखना चाहते हैं , तो आप `` उद्धरण का उपयोग कर सकते हैं ।

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

कहीं और आपको स्ट्रिंग या चर के साथ कॉनैट की आवश्यकता है , आप उपयोग कर सकते हैं

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>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.