web-dev-qa-db-fra.com

Définir la couleur du texte à l'aide de la liaison de données sur Android

J'essaie de définir la couleur du texte TextView à l'aide de la bibliothèque de liaison de données

Android:textColor="@{holder.getTitleColor(context, item)}"

où la méthode dans la classe Holder est définie comme ci-dessous

public int getTitleColor(Context context, Item item) {
   ...
}

Peu importe si je retourne color int (@ColorInt) ou ressource de couleur (@ColorRes), le texte est peint en blanc. Qu'est-ce que je fais mal?

8
tomrozb

Il semble que la int que vous fournissez soit interprétée comme une couleur hexadécimale, même s'il semble intuitif que ce programme de paramétrage s'attende à un identifiant de ressource.

utilisez la référence Context générée pour chaque vue pouvant être liée, et utilisez-la pour convertir l'ID de ressource en couleur vers laquelle vous pointez, comme décrit dans le Guide de développement DataBinding :

Une variable spéciale nommée context est générée pour être utilisée dans les expressions de liaison en fonction des besoins. La valeur de context est le contexte de getContext () de la vue racine.

utilisez-le pour définir la couleur comme ceci:

 <TextView
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="@{data.text}"
            Android:textColor="@{context.getColor(data.colorRes)}"
            />
18
Mardann

créer une méthode en utilisant BindingAdapter

@BindingAdapter({"bind:color"})
public static void setFont(TextView textView, Item item) {
    textView.setTextColor(<set color of your choice>);
}

et l'appeler depuis xml

app:color="@{item}"
5
Ravi Rupareliya

Pour définir une couleur sur une partie de la chaîne - Cela fonctionne parfaitement avec Kotlin, les ressources de chaîne et la liaison de données


  • Ajoutez votre adaptateur de liaison (placez-le en dehors de toutes vos classes)

    @BindingAdapter("app:full_text", "app:span_text", "app:span_color")
    fun formatText(textView: TextView, full_text: String, span_text: String, span_color: Int) {
        val firstMatchingIndex = full_text.indexOf(span_text)
        val lastMatchingIndex = firstMatchingIndex + span_text.length
        val spannable = SpannableString(full_text)
        spannable.setSpan(ForegroundColorSpan(span_color), firstMatchingIndex, lastMatchingIndex, Spannable.SPAN_INCLUSIVE_EXCLUSIVE)
        textView.text = spannable
    }
    
  • Configuration des ressources de chaîne avec des variables

    <string name="percentage">%1$d\%%</string>
    <string name="booking_fee">Require card and collect %1$s at Booking</string>
    
  • Convertit la valeur en chaîne dans votre ViewHolder (si nécessaire)

    fun bind(percentage: Int) {
        binding.percentage = context.resources.getString(R.string.percentage, percentage)
        binding.executePendingBindings()
    }
    
  • Appliquer des liaisons via votre layout xml

    <data>
        <variable
            name="percentage"
            type="String" />
    </data>
    
    <TextView
        ...
        app:full_text="@{@string/booking_fee(percentage)}"
        app:span_color="@{@color/color_primary}"
        app:span_text="@{percentage}" />
    

Résultat:

 enter image description here


_ {N'utilisez pas Android:text="..." dans votre fichier de mise en page} _

1
Michael

Créez l'adaptateur de liaison comme suit, je passe toutes les chaînes à colorier dans {}. Remplacez la chaîne {blah} par la chaîne blah colorée dans la plage.

@BindingAdapter( "spanColor")
fun formatText(view:TextView, hexColorValue:Int) {
    val text = view.text
    val span = SpannableStringBuilder(text)
    var i = 0
    var diff = 0
    while (i < text.length) {
        val firstIndex = text.indexOf('{', i) - diff
        val secondIndex = text.indexOf('}', i) - diff
        if (firstIndex < 0 || secondIndex < 0) break
        span.delete(firstIndex, firstIndex + 1)
        span.delete(secondIndex - 1, secondIndex)
        span.setSpan(ForegroundColorSpan(hexColorValue), firstIndex, secondIndex-1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        i = secondIndex + diff + 1
        diff += 2
    }
    view.text = span
}

Dans votre fichier XMl, utilisez l’attribut (app:spanColor="@{@color/colorAccent}") comme 

 <TextView
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:gravity="center"
                Android:layout_marginTop="@dimen/space_xlarge"
                style="@style/DefaultSmallText"
                app:spanColor="@{@color/colorAccent}"
                Android:text="@string/create_credential_message"/>

string.xml

<string name="create_credential_message"><![CDATA[{Username} must at least contain 8 alphanumeric characters or an email address. {Password} must be 8-20 characters long, contain uppercase, lowercase, number, & special characters.]]></string>
0
Tasneem