I want to use the ternary operator to change the color of a custom view in terms of a Boolean. Here is my custom view
class AddButton(context: Context, attrs: AttributeSet): RelativeLayout(context, attrs) {
private var imageView: AppCompatImageView
private var textView: TextView
init {
inflate(context, R.layout.add_button, this)
imageView = findViewById(R.id.add_button_icon)
textView = findViewById(R.id.add_button_text)
val attributes = context.obtainStyledAttributes(attrs, R.styleable.AddButton)
val iconTint = attributes.getResourceId(R.styleable.AddButton_iconColor, 0)
imageView.setImageDrawable(attributes.getDrawable(R.styleable.AddButton_icon))
textView.text = attributes.getString(R.styleable.AddButton_text)
setIconTint(iconTint)
attributes.recycle()
}
fun setIconTint(colorId: Int) {
imageView.setColorFilter(ContextCompat.getColor(context, colorId), android.graphics.PorterDuff.Mode.SRC_IN);
}
fun setText(text: String) {
textView.text = text
}
}
values/attr.xml :
<declare-styleable name="AddButton">
<attr name="icon" format="reference"/>
<attr name="iconColor" format="color"/>
<attr name="text" format="string"/>
</declare-styleable>
In the layout :
<com.my.package.ui.customview.AddButton
app:icon="@drawable/ic_add"
app:iconColor="@{selected ? @color/colorRed : @color/colorBlack}"
app:text="@{selected ? @string/selected : @string/not_selected}"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
It is working as expected for the app:text but when i want to do it for the iconColor i have this error :
Cannot find a setter for <com.my.package.ui.customview.AddButton app:iconColor> that accepts parameter type 'int'
For now to solve the problem, i have to change the color in the code behind by listening when the selected boolean changes and then call the setIconTint of my AddButton view.
Is there a way to change the color directly in the layout file using the ternary operator ?
You are looking for a custom data binding adapter for your custom view. First, check out this for the complete document.
So, in short, you need to define a method named: setIconColor
that accepts iconId
and sets the icon color by the provided resource id.
But if you want to use your current method named setIconTint
, you just need to annotate your class with:
@BindingMethods(value = [
BindingMethod(
type = AddButton::class,
attribute = "iconColor",
method = "setIconTint")])
After all, I again suggest you check other variants of binding adapters in the official document.