Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get an enum which is created in attrs.xml in code

People also ask

How do you find enums?

To get the value of enum we can simply typecast it to its type. In the first example, the default type is int so we have to typecast it to int. Also, we can get the string value of that enum by using the ToString() method as below.

What is enum in XML?

This annotation, together with XmlEnum provides a mapping of enum type to XML representation. An enum type is mapped to a schema simple type with enumeration facets. The schema type is derived from the Java type specified in @XmlEnum.value().

What is enum code?

An enumeration, or Enum , is a symbolic name for a set of values. Enumerations are treated as data types, and you can use them to create sets of constants for use with variables and properties.


There does not seem to be an automated way to get a Java enum from an attribute enum - in Java you can get the numeric value you specified - the string is for use in XML files (as you show).

You could do this in your view constructor:

TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.IconView,
                0, 0);

    // Gets you the 'value' number - 0 or 666 in your example
    if (a.hasValue(R.styleable.IconView_icon)) {
        int value = a.getInt(R.styleable.IconView_icon, 0));
    }

    a.recycle();
}

If you want the value into an enum you would need to either map the value into a Java enum yourself, e.g.:

private enum Format {
    enum_name_one(0), enum_name_n(666);
    int id;

    Format(int id) {
        this.id = id;
    }

    static Format fromId(int id) {
        for (Format f : values()) {
            if (f.id == id) return f;
        }
        throw new IllegalArgumentException();
    }
}

Then in the first code block you could use:

Format format = Format.fromId(a.getInt(R.styleable.IconView_icon, 0))); 

(though throwing an exception at this point may not be a great idea, probably better to choose a sensible default value)


It's simple let's show everybody an example just to show how easy it is:

attr.xml:

<declare-styleable name="MyMotionLayout">
    <attr name="motionOrientation" format="enum">
        <enum name="RIGHT_TO_LEFT" value="0"/>
        <enum name="LEFT_TO_RIGHT" value="1"/>
        <enum name="TOP_TO_BOTTOM" value="2"/>
        <enum name="BOTTOM_TO_TOP" value="3"/>
    </attr>
</declare-styleable>

Custom layout:

public enum Direction {RIGHT_TO_LEFT, LEFT_TO_RIGHT, TOP_TO_BOTTOM, BOTTOM_TO_TOP}
Direction direction;
...
    TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.MyMotionLayout);
    Direction direction = Direction.values()[ta.getInt(R.styleable.MyMotionLayout_motionOrientation,0)];

now use direction like any other enumeration variable.


Let me add a solution written in kotlin. Add inline extension function:

inline fun <reified T : Enum<T>> TypedArray.getEnum(index: Int, default: T) =
    getInt(index, -1).let { if (it >= 0) enumValues<T>()[it] else default 
}

Now getting enum is simple:

val a: TypedArray = obtainStyledAttributes(...)
val yourEnum: YourEnum = a.getEnum(R.styleable.YourView_someAttr, YourEnum.DEFAULT)
a.recycle()

Well for sanity's sake. Make sure your ordinals are the same in your declared styleable as in your Enum declaration and access it as an array.

TypedArray a = context.getTheme().obtainStyledAttributes(
                   attrs,
                   R.styleable.IconView,
                   0, 0);

int ordinal = a.getInt(R.styleable.IconView_icon, 0);

if (ordinal >= 0 && ordinal < MyEnum.values().length) {
      enumValue = MyEnum.values()[ordinal];
}

I know it's been a while since the question was posted, but I had the same issue recently. I hacked a little something together that uses Square's JavaPoet and some stuff in the build.gradle that automatically creates a Java enum class from the attrs.xml on project build.

There's a little demo and a readme with an explanation at https://github.com/afterecho/create_enum_from_xml

Hope it helps.