Android: CardView foreground using databinding

I'm trying to fill my RecyclerView with CardViews, the CardViews use Android databinding to set Attributes like Texts in TextViews. On Items that aren't finished jet I want to add a greyish overlay. But unfortunately the foreground android:foreground="@{viewModel.getState != State.FINISHED? @color/gray_transparent54 : null}"> is not applied. On the other hand, if I force the foreground color android:foreground="@grey_transparent54">, it works it is.

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <data class="ListItemBinder">
        <import type="myProject.State"/>
        <import type="android.view.View"/>
        <variable
            name="viewModel"
            type="myProject.ListItemViewModel"/>
    </data>

    <android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="80dp"
        card_view:cardCornerRadius="4dp"
        android:foreground="@{viewModel.getState != State.FINISHED? @color/gray_transparent54 : null}">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{viewModel.getName}"
                tools:text="Name"
                android:textColor="@color/color_text_primary"
                android:textSize="24sp"/>
    </android.support.v7.widget.CardView>
</layout>

Thanks in advance.

Answers


Unless you've implemented getters like getGetState() and getGetName() I think you're accessing your viewModel fields incorrectly. Although you didn't post your ListItemViewModel I suspect you need something closer to this:

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="80dp"
    card_view:cardCornerRadius="4dp"
    android:foreground="@{viewModel.state != State.FINISHED? @color/gray_transparent54 : null}">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{viewModel.name}"
            tools:text="Name"
            android:textColor="@color/color_text_primary"
            android:textSize="24sp"/>
</android.support.v7.widget.CardView>

Data binding automatically looks for a method in your ListItemViewModel class named "getName()" when you access @{viewModel.name}, "getState()" when you access @{viewModel.state} etc.

Note: although UI logic is generally ok, be wary of putting business logic in your XML, as it can limit your flexibility and make testing/debugging more difficult.

Know also that you cannot mix types when using the ternary (?:) operator, so something like choosing between a color int and a drawable will not work. However, you can easily work around this by using custom BindingAdapter methods, e.g. make a binding adapter that takes your ListItemViewModel as a parameter, and put all your logic for what type of value to set within the method itself.


Need Your Help

Get the key corresponding to the minimum value within a dictionary

python dictionary min minimum idioms

If I have a Python dictionary, how do I get the key to the entry which contains the minimum value?