Android 如何在代码中获取在attrs.xml中创建的枚举

Android 如何在代码中获取在attrs.xml中创建的枚举,android,enums,android-custom-view,attr,custom-view,Android,Enums,Android Custom View,Attr,Custom View,我创建了一个自定义视图(find-it),它具有类型为enum的declare-styleable属性。在xml中,我现在可以为自定义属性选择一个枚举项。现在我想创建一个方法以编程方式设置此值,但我无法访问枚举 attr.xml <declare-styleable name="IconView"> <attr name="icon" format="enum"> <enum name="enum_name_one" value="0"/&g

我创建了一个自定义视图(find-it),它具有类型为enum的declare-styleable属性。在xml中,我现在可以为自定义属性选择一个枚举项。现在我想创建一个方法以编程方式设置此值,但我无法访问枚举

attr.xml

<declare-styleable name="IconView">
    <attr name="icon" format="enum">
        <enum name="enum_name_one" value="0"/>
        ....
        <enum name="enum_name_n" value="666"/>
   </attr>
</declare-styleable>     
<com.xyz.views.IconView
    android:id="@+id/heart_icon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:icon="enum_name_x"/>

....
layout.xml

<declare-styleable name="IconView">
    <attr name="icon" format="enum">
        <enum name="enum_name_one" value="0"/>
        ....
        <enum name="enum_name_n" value="666"/>
   </attr>
</declare-styleable>     
<com.xyz.views.IconView
    android:id="@+id/heart_icon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:icon="enum_name_x"/>

我需要的是:
mCustomView.setIcon(R.id.enum\u name\u x)

但是我找不到枚举,或者我甚至不知道如何获得枚举或枚举的名称

从属性枚举中获取Java枚举似乎没有一种自动的方法-在Java中,您可以获取指定的数值-字符串用于XML文件(如您所示)

您可以在视图构造函数中执行此操作:

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();
}
如果要将值映射到枚举中,则需要自己将值映射到Java枚举中,例如:

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();
    }
}
然后在第一个代码块中,您可以使用:

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

(虽然此时抛出异常可能不是一个好主意,但最好选择一个合理的默认值)

为了理智起见。确保所声明的可样式化中的序号与枚举声明中的序号相同,并将其作为数组访问

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];
}
TypedArray a=context.getTheme().ActainStyledAttributes(
属性,
R.styleable.IconView,
0, 0);
int ordinal=a.getInt(R.styleable.IconView_图标,0);
if(序号>=0&&ordinal
我知道问题发布已经有一段时间了,但最近我遇到了同样的问题。我用Square的javapoter和build.gradle中的一些东西拼凑了一个小东西,在项目构建时自动从attrs.xml创建一个Java枚举类

这里有一个小演示和自述,并在


希望能有所帮助。

很简单,让我们给每个人看一个例子来说明这是多么简单:

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>

现在像使用任何其他枚举变量一样使用direction。

让我添加一个用kotlin编写的解决方案。添加内联扩展函数:

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

我认为在这里依赖枚举序号注定会产生不可靠的代码。一件事会被更新,而另一件事不会被更新,那么你会遇到麻烦。那么,有什么更好的方法来更新呢?总之,只需使用此方法来获取Enum attr:TypedArray.getInt(R.styleable.name\u your\u define,defaultValue)@CalvinChe,,它返回一个
int
。史蒂夫·莫雷茨有。我因为没看到它而感到很傻,但现在是凌晨4:30。睡觉时间到了……是的,就这么简单。答案只是一个更好地说明它的例子。但这只是两个平行的符号定义。只有在定义相同的情况下,这才有效——也就是说,它是脆弱的。OP希望代码能够访问从XML生成的枚举。似乎这应该是可能的。@SteveWhite由于您无法访问xml,因此无法将其自动化并让其依赖于一个定义。这是实现这一点的最干净(可能)的方法。如果您可以解析xml并以一种非常好的方式访问它,但您不能。(除非您可以但不在代码中,否则您可以编写一个插件来读取xml并将值提取到您的java中,这样它就会被同步,这样它就不会因为自动化而变得脆弱。)这是最干净的方法。但是,如果可以在一个位置进行枚举到id的映射,效果会更好。通过这种方法,我们必须在xml属性和枚举类中定义映射。