Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android data binding with conditional resources

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>
like image 877
jlhonora Avatar asked Nov 26 '15 19:11

jlhonora


People also ask

Can we use DataBinding and ViewBinding together?

Yep, we don't use <layout> ViewBinding, because on DataBinding we must add that layout tag to generate Binding class and it's different with ViewBinding which automatically generates all layout to Binding class.

What is difference between ViewBinding and binding Android?

View binding and data binding both generate binding classes that you can use to reference views directly. However, view binding is intended to handle simpler use cases and provides the following benefits over data binding: Faster compilation: View binding requires no annotation processing, so compile times are faster.

Can we use DataBinding in MVP?

Combining Databinding along wih MVP pattern can result in a very clean structure and maintainable project. Databinding saves u a lot of stress and uneccesary long lines of code. Your UI is updated eaily and gone are those days where you need "findViewById" and onclick listeners and so on.

What is 2 way data binding in Android?

Stay organized with collections Save and categorize content based on your preferences. The @={} notation, which importantly includes the "=" sign, receives data changes to the property and listen to user updates at the same time. // Avoids infinite loops.


1 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.

like image 108
Shirane85 Avatar answered Oct 12 '22 22:10

Shirane85