web-dev-qa-db-fra.com

Comment utiliser la liaison de données pour combiner une chaîne de ressources avec une variable dynamique en XML?

J'ai un TextView qui a une chaîne codée en dur et j'ai une variable dynamique que je veux mettre à la fin de cette chaîne. Ceci est mon code:

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

J'ai un problème avec Android:text="@string/Generic_Text"+"@{ Profile.name }". Le Generic_Text indique "Mon nom est", puis le Profile.name est dynamique et change évidemment de profil en profil. Je le veux pour que toute la sortie TextView soit Mon nom est {Profile.name}. Toute aide est la bienvenue.

93
Ignacio Perez

Tu peux le faire:

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

si vous utilisez le formatage de chaîne pour votre chaîne Generic_Text. ex. %s à la fin

102
C0D3LIC1OU5

Vous pouvez le faire encore plus simplement:

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

votre chaîne devrait être comme ça:

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

Modifier:

  1. Bien sûr, vous pouvez utiliser autant de variables que nécessaire:

    Android:text= "@{@string/generic_text(profile.firstName, profile.secondName)}"
    
    <string name="generic_text">My Name is %1$s %2$s</string>
    
  2. Cela fonctionne simplement parce qu'il est conçu dans la liaison de données. Plus dans docs: https://developer.Android.com/topic/libraries/data-binding/expressions#resources

271
Roman_D

Beaucoup de façons de concaténer des chaînes

1. Utilisation de la ressource chaîne ( recommandée car localisation )

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

Faites juste une ressource de chaîne comme ceci.

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

2. Concat codé en dur

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

Ceci est utile lorsque vous avez besoin d’ajouter un code codé en dur, comme + pour le numéro de téléphone.

3. Utilisation de la méthode concat de String

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

Ici space est une entité HTML qui est placée à l'intérieur de strings.xml. Parce que XML n'accepte pas directement les entités HTML ni les caractères spéciaux. (Link Html Entities)

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

4. Utilisation de String.format()

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

vous devez importer la classe String dans la présentation dans ce type.

<?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. concaténer deux chaînes par ressource de chaîne.

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

Dans ce cas, placez une ressource chaîne dans strings.xml

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

Il peut y avoir de nombreuses autres façons, choisissez celle dont vous avez besoin.

37
Khemraj

Mise à jour 2019, Android studio vers 3.4, Android Gradle Plugin to 3.4

Plus besoin d'importer

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

pour les opérations sur les chaînes. Veuillez vérifier ceci réponse .

2
SANAT

Dans le cas où vous ne pouvez pas modifier la chaîne de ressource afin qu'elle contienne %s à la fin (par exemple, car elle est utilisée ailleurs sans suffixe):

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

Si Profile.name ne peut pas être nul, c'est suffisant. Cependant, si un null se produit, il se bloquera. Vous devez ajouter une autre couche:

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

(qui nécessite <import type="Java.util.Objects"/> pour fonctionner.)

Encore une fois: tout ce travail supplémentaire ne vaut la peine que si la chaîne de ressources est utilisée ailleurs. La deuxième raison est lorsque vous voulez traiter null comme "chaîne vide" au lieu d'un littéral "null".

1
Agent_L