Leos Literak Leos Literak - 3 months ago 11
Android Question

Android custom state button does not work

I have found this interesting answer about implementing custom drawable states using selectors. I copied the source code and added my activity that use custom button. But it does not work - created buttons are grey. Setters are never called. This should lead to a state when a green item_raw background is used.

Complete code is at GitHub: https://github.com/literakl/DressUp/commit/4357f32773f4dbe15c05a3565e9fa39cdba4cee3

My changes to original answer follow. First is namespace copied from the Manifest's package:

<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/sandbox.lelisoft.com.dressup">


Layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<sandbox.lelisoft.com.dressup.FoodButton
android:layout_height="60dp"
android:layout_width="150dp"
app:state_baked="false"
app:state_fried="true"
/>


What silly mistake have I made?

Answer

It works finally. The first problem was missing background attribute, the second was missing attribute setting in constructor.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<sandbox.lelisoft.com.dressup.FoodButton
    android:id="@+id/foodButton"
    android:layout_height="60dp"
    android:layout_width="150dp"
    android:layout_margin="@dimen/activity_horizontal_margin"
    app:state_baked="false"
    app:state_fried="true"
    android:background="@drawable/food_button"
    />

And

public FoodButton(Context context, AttributeSet attrs) {
    super(context, attrs);
    for (int i=0;i<attrs.getAttributeCount();i++) {
        switch (attrs.getAttributeName(i)) {
            case "state_baked": mIsBaked = attrs.getAttributeBooleanValue(i, false); break;
            case "state_fried": mIsFried = attrs.getAttributeBooleanValue(i, false); break;
        }
    }
}

And

<resources>
    <attr name="state_fried" format="boolean" />
    <attr name="state_baked" format="boolean" />
</resources>

Complete code is at https://github.com/literakl/DressUp/tree/states_branch, diff at https://github.com/literakl/DressUp/commit/5995445fc66d1e31abe68d06ee556fdf6416da26