データバインディングライブラリを使用してTextView
テキストの色を設定しようとしています
Android:textColor="@{holder.getTitleColor(context, item)}"
Holder
クラスのメソッドは以下のように定義されています
public int getTitleColor(Context context, Item item) {
...
}
Color int(@ColorInt
)またはカラーリソース(@ColorRes
)テキストを白く塗りつぶします。何が悪いのですか?
あなたが提供しているint
は、16進数の色として解釈されているようですが、このセッターはリソースIDを想定しているはずです。
バインド可能な各ビューに対して生成されたContext
参照を使用し、それを使用して、リソースIDを指している色に変換します DataBinding Dev Guideで説明 :
必要に応じてバインディング式で使用するために、contextという名前の特別な変数が生成されます。 contextの値は、ルートビューのgetContext()のContextです。
これを使用して、次のように色を設定します。
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="@{data.text}"
Android:textColor="@{context.getColor(data.colorRes)}"
/>
BindingAdapter
を使用してメソッドを作成する
@BindingAdapter({"bind:color"})
public static void setFont(TextView textView, Item item) {
textView.setTextColor(<set color of your choice>);
}
そしてそれをxmlから呼び出す
app:color="@{item}"
文字列の一部を色に設定する場合-これはKotlin、文字列リソース、Databindingと完全に連携します
バインディングアダプタを追加します(これをすべてのクラスの外側に配置します)
@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
}
変数を使用して文字列リソースをセットアップします
<string name="percentage">%1$d\%%</string>
<string name="booking_fee">Require card and collect %1$s at Booking</string>
ViewHolderで値を文字列に変換します(必要な場合)
fun bind(percentage: Int) {
binding.percentage = context.resources.getString(R.string.percentage, percentage)
binding.executePendingBindings()
}
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}" />
結果:
レイアウトファイルでAndroid:text="..."
を使用しないでください
整数から色を設定するには、次を呼び出します。
Android:textColor="@{data.color}"
object CustumBinderAdapter {
@JvmStatic
@BindingAdapter("text_color")
fun setTextColor(view: TextView, color: Int) {
when(color){
R.color.soft_green->{
view.setTextColor(Color.parseColor("#5abc6e"))
}
R.color.deep_orange->{
view.setTextColor(Color.parseColor("#e62e30"))
}
}
}
}
そしてXMLでは次のように使用します:
app:text_color="@{yourViewModel.yourIntColorValue}"
私の解決策は、このTextView宣言をxmlで使用することでした:
<TextView
...
Android:textColor="@{model.getResultColor(context, index)}"
...
/>
そしてviewModelのこのメソッド:
fun getResultColor(index: Int): Int {
getItem(index)?.let { item ->
...
return Color.GRAY
}
バインディングアダプターを使用してから、カラーリソースを使用することもできます。
このメソッドをプロジェクトの任意の場所で定義します。
@BindingAdapter(value = "text_color") //customise your name here
public static void setTextColor(TextView view, int color) {
view.setTextColor(color);
}
次に、XMLで新しい属性を使用します。
<TextView
app:text_color="@{@color/colorPrimary}"/>
次のようにバインディングアダプタを作成します。ここでは、{}
内で色付けするすべての文字列を渡します。スパンの{blah}
文字列を色付きのblah
文字列に置き換えます。
@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
}
XMlファイルで、属性(app:spanColor="@{@color/colorAccent}"
)を次のように使用します
<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>