Home » Android » Android data binding with conditional resources

Android data binding with conditional resources

Posted by: admin May 14, 2020 Leave a comment

Questions:

Here’s a typical usage of Android’s data-binding:

android:background="@{isError ? @color/red : @color/white}"

It gets harder when the state can adopt multiple values. Edit: using the status attribute in the method call was the only way to make it work:

android:background="@{Check.getStatusColor(check.status)}"

and define the static method (does not have @Bindable):

public int getStatusColor(int status) {
    switch (status.get()) {
        case STATUS_OK:
            return ContextCompat.getColor(context, R.color.success);
        case STATUS_WARNING:
            return ContextCompat.getColor(context, R.color.warning);
        case STATUS_ERROR:
            return ContextCompat.getColor(context, R.color.error);
        default:
            return ContextCompat.getColor(context, R.color.idle);
    }
}

How can I achieve this, without putting nested ternary operators in the XML (which I don’t find very elegant, btw), or without passing the check.status attribute?

EDIT: Add XML:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <import type="org.honorato.diagnostics.models.Check"/>
        <variable
            name="check"
            type="Check"/>
    </data>
    <LinearLayout
        android:background="@android:color/white"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="72dp"
        >

        <LinearLayout
            android:padding="16dp"
            android:layout_width="0dip"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:text="@{check.title}"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@android:color/primary_text_light"
                android:textStyle="bold" />

        </LinearLayout>

        <ImageView
            android:padding="16dp"
            android:src="@{check.getStatusDrawable(check.status)}"
            android:background="@{check.getStatusColor(check.status)}"
            android:layout_width="72dp"
            android:layout_height="match_parent"
            android:layout_gravity="center_vertical|center_horizontal" />

    </LinearLayout>
</layout>
How to&Answers:

I will do that in this way:

android:background="@{check.getStatusColor()}"

getStatusColor is a non static method of Check and this why we have access to our instance field status

public int getStatusColor() {
    switch (status) {
        case STATUS_OK:
            return ContextCompat.getColor(context, R.color.success);
        case STATUS_WARNING:
            return ContextCompat.getColor(context, R.color.warning);
        case STATUS_ERROR:
            return ContextCompat.getColor(context, R.color.error);
        default:
            return ContextCompat.getColor(context, R.color.idle);
    }
}

This should work.