普段何気なく使っていた、android:background
で少し躓いたので、その解決策を記録に残します。
何が起こったか
activity_main.xml
...
<data>
<variable
name="colorResId"
type="Integer"
/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@{ colorResId }"
tools:context=".MainActivity"
>
...
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.colorResId = R.color.colorBlack
}
}
colors.xml
<resources>
<color name="colorPrimary">#6200EE</color>
<color name="colorPrimaryDark">#3700B3</color>
<color name="colorAccent">#03DAC5</color>
<color name="colorBlack">#000000</color>
</resources>
DataBindingを用いてresourceに定義されているcolorをbackgroundに反映させるようなコードを書いた時に、指定しているcolorになってくれなかった(今回はR.color.black
)。
原因
android:background
について調べることになるとは思わなかったが、調べてみました。 何やら、android:background
は、引数にDrawable
を期待しているらしい。 おそらく、colorのresourceID(整数値)を渡すことを想定していないので、思い通りの挙動をしてくれない。(意識して使ってなかったが、思い通りの挙動をしてくれた時もあったような…)
解決策
解決策として、BindingAdapterを作成することにしました。
BindingAdapter.kt
@BindingAdapter("colorResId")
fun View.setColorResId(@ColorRes colorResId: Int?) {
colorResId?.let {
val color = this.context.getColor(it)
this.setBackgroundColor(color)
}
}
activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
colorResId="@{ colorResId }" // 作成したBindingAdapter
tools:context=".MainActivity"
>
作成してBindingAdapterで行っていることは、
- colorResIdを受け取る
- colorResIdからcolorを取得
- backgroundにcolorをセットする
最後に作成した、BindingAdapterをxmlに書くだけ。