Forum Xamarin.Android

Custom attributes for multi-state button

I'm having trouble writing a custom multi-state button. I stated by defining three states in Resource/values/attrs.xml like this:

<resources>
    <declare-styleable name="FlashButton">
        <attr name="state_auto" format="boolean" />
        <attr name="state_off" format="boolean" />
        <attr name="state_on" format="boolean" />
    </declare-styleable>
</resources>

Then defining a drawable that queries the state like this:

<selector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res/overlay">
    <item android:drawable="@drawable/camera_flash_btn_off" custom:state_off="true" />
    <item android:drawable="@drawable/camera_flash_btn_on" custom:state_on="true" />
    <item android:drawable="@drawable/camera_flash_btn_auto" custom:state_auto="true" />
</selector>

And referencing it in my main activity layout like this:

 <overlay.FlashButton
            android:id="@+id/flash"
            android:layout_width="53dp"
            android:layout_height="32dp"
            android:background="@drawable/flash" />

Supported by a custom Button class like this (maybe not so relevant):

namespace overlay
{
    class FlashButton:Button
    {
        private static int[] FlashAutoSet = {Resource.Attribute.state_auto};
        private static int[] FlashOffSet = {Resource.Attribute.state_off};
        private static int[] FlashOnSet = {Resource.Attribute.state_on};

        private int _state = 0;

        public FlashButton (Context context, IAttributeSet attrs, int defStyle) :
            base (context, attrs, defStyle)
        {
        }

        public FlashButton (Context context, IAttributeSet attrs) :
            base (context, attrs)
        {
        }

        protected override int[] OnCreateDrawableState (int extraSpace)
        {
            int[] baseState = base.OnCreateDrawableState (extraSpace + 3);
            if (_state == 0) {
                MergeDrawableStates (baseState, FlashAutoSet);
            }
            if (_state == 1) {
                MergeDrawableStates (baseState, FlashOffSet);
            }
            if (_state == 2) {
                MergeDrawableStates (baseState, FlashOnSet);
            }
            return baseState;
        }
    }
}

When I try to build I get these errors:
obj/Debug/res/drawable/flash.xml:1: error: No resource identifier found for attribute 'state_off' in package 'overlay'
obj/Debug/res/drawable/flash.xml:1: error: No resource identifier found for attribute 'state_on' in package 'overlay'
obj/Debug/res/drawable/flash.xml:1: error: No resource identifier found for attribute 'state_auto' in package 'overlay'
(overlay)

Can someone help me out here? I suspect it has something to do with my xml name space, but can't nail it.

Posts

  • CheesebaronCheesebaron DKInsider, University mod

    Try using http://schemas.android.com/apk/res-auto as namespace instead.

  • JannieTheunissenJannieTheunissen GBMember ✭✭
    edited July 2013

    Ha! That got my code compiling. But now I hit a runtime exception:

    Unable to activate instance of type overlay.FlashButton from native handle 4051f7f8

    System.Exception: No constructor found for overlay.FlashButton::.ctor(System.IntPtr, Android.Runtime.JniHandleOwnership)

  • CheesebaronCheesebaron DKInsider, University mod

    Well as it says you are missing a ctor with that signature. So in your FlashButton class add:

    public FlashButton (System.IntPtr handle, Android.Runtime.JniHandleOwnership owner) :
        base (handle, owner)
    
  • JannieTheunissenJannieTheunissen GBMember ✭✭

    Of course! Thanks a lot.

Sign In or Register to comment.