Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two-way data binding for android:enabled attribute

I'm trying to figure out the two-way data binding library in Android. I want to enable/disable the LinearLayout (and the RelativeLayout inside) by changing the android:enabled attribute in the xml.

The XML part looks like this:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center_vertical"
    android:layout_margin="5dp"
    android:gravity="center"
    android:enabled="@={viewModel.asd}"
    ndroid:onClick="@{()-> viewModel.doSomething()}"
    android:background="@drawable/shortcut_button_label_selector"
    android:orientation="horizontal">

    <RelativeLayout
        android:layout_width="40dp"
        android:layout_height="match_parent"
        android:enabled="@={viewModel.asd}"
        android:background="@drawable/shortcut_button_icon_selector">

Now, the reason I want to do this is because of these two selectors (shortcut_button_label_selector and shortcut_button_icon_selector), they look like this:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:state_enabled="false"
        android:drawable="@color/grey_300"></item>
    <item
        android:state_enabled="true"
        android:drawable="@color/menubar_background"></item>

</selector>

I want to be able to dynamically change the background based on the enabled attribute on the View. The reason why I've chosen the enabled attribute is that I got the onClick event on that the LinearLayout and I need to disable it (making it unclickable); I had the same issue with the android:clickable attribute.

Thing is when I try to compile it I'm getting the error

java.lang.RuntimeException: Found data binding errors. ****/ data binding error ****msg:Cannot find the getter for attribute 'android:enabled' with value type boolean on android.widget.LinearLayout.

The viewModel.asd is just a public boolean / ObservableBoolean, I've tried both.

Can anyone explain what's going on and why am I getting the error? I can see the isEnabled / setEnabled methods in the View class (that Layouts extend).

Is there any way I can move on with my approach or do I have to change it entirely?

//EDIT: I might not need a two-way binding.. I don't know anymore // EDIT continued: It might have to do something with my ViewModel inheritance:

The layout file has a viewModel of type a.b.MainViewModel, but the field asd is int the a.b.BaseViewModel (MainViewModel extends BaseViewModel). Now what I'd want it to so is if I update the asd field from any other view extending the BaseViewModel it would automatically update the enabled attribute..

It doesn't work with Strings either.. I guess it's the inheritance thing

Kind regards, Marcin

like image 784
Marcin Avatar asked Mar 18 '17 18:03

Marcin


1 Answers

There could be multiple reasons for your error. The first is that 2-way data binding doesn't work with the android:enabled attribute. This is because there is no callback to tell data binding that the property has changed.

2-way data binding works with most attributes in which the user enters data, so it is easiest to think of it as getting the data from the user to the model.

Another reason why you might receive an error like that is the model may not have a bindable property. You should use either an Observable:

public class ViewModel extends BaseObservable {
    private boolean asd = true;

    @Bindable
    public boolean getAsd() { return asd; }

    public void setAsd(boolean asd) {
        this.asd = asd;
        notifyPropertyChanged(this, BR.asd);
    }
}

or use ObservableFields:

public class ViewModel {
    public final ObservableBoolean asd = new ObservableField(true);
}

Without this, one way data binding will only work the first time -- if you change the ViewModel, the UI won't update.

It doesn't appear that you need 2-way data binding for the android:enabled attribute. One way data should work fine to change the state of the selector.

like image 125
George Mount Avatar answered Oct 23 '22 04:10

George Mount