Search code examples
androidandroid-databindingandroid-imagebutton

Why does "enabled" and "pressed" attributes work for ImageButton?


Where to see a list of all attributes of all view types in Android?

I got an impression, that ImageButton does not have enabled and pressed attributes. At least, they didn't work when I set them in XML. Also I found a lot of "guides" on how to make these button either disabled and/or pressed.

Simultaneously, when I bound them with data binding

   <ImageButton
            android:id="@+id/locate_button"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:layout_toRightOf="@id/bookmark_button"

            android:enabled="@{activity.locateEnabled}"
            android:pressed="@{activity.locatePressed}"
            android:onClick="@{activity.onLocateClick}"


            android:src="@drawable/locate_selector"
            android:background="@null"
            />

they just worked. Both pressed and enabled. At the same moment pressed is even reported as unknown property by Android Studion spell checked!

So, what is it?

1) by-design behaviour and I just don't understand something (what?)

2) sugar from data binding library

3) hacking

4) ????

How to know, how poratble is this feature?


Solution

  • The answer is both 1 and 2. Data binding will allow you use an attribute to call any setter on a View. You can look at the data binding guide's section on attribute setters.

    When you set the android:enabled attribute, you are using Android data binding's the automatic setters to calls setEnabled(). Android data binding sees the attribute name (enabled) and looks for a setter with that name and finds setEnabled(). The same is true for android:pressed -- there is a setPressed() method. Yay for convention!

    android:onClick is a real attribute, but data binding doesn't use it. There is no setOnClick() method, either. Instead, there is a Binding Adapter that sets an OnClickListener to call your onLocateClick() method. There is a bit of magic involved in this that relies on the Annotation Processor that data binding uses to examine your code, but suffice it to say that it does this at compile time instead of using runtime reflection.

    All event listeners should have Binding Adapters written for them with the same name as the event (as opposed to the listener name). So, you can also set android:onLongClick, for example. You may also be interested in the lambda syntax for events.

    I'm not sure what you mean by "portable." Data Binding is usable at least back to Gingerbread (we claim Froyo, but really, who targets Froyo?), but you won't be able to transfer it to iOS or anything like that. All of Android data binding is done with a small runtime library and generated code. You don't have to worry about specific versions of Android.