我希望将以下属性添加到我在Android中构建的自定义视图中:
<attr name="sourceType" format="enum">
<enum name="generic" value="???" />
<enum name="dash" value="???" />
<enum name="smooth_streaming" value="???" />
<enum name="hls" value="???" />
</attr>
在我的代码内部,我想使用一个枚举来表示各种源类型:
public enum SourceType {
Generic, DASH, SmoothStreaming, HLS;
}
但是在我的自定义视图中,我不确定如何将属性值转换为枚举:
public BFPlayer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.BFPlayer);
// Clearly wrong:
// 1. SourceType.Generic cannot be cast to int
// 2. int cannot be cast to SourceType
SourceType sourceType = attributes.getInt(R.styleable.BFPlayer_sourceType, SourceType.Generic);
}
我已经考虑做以下事情:
attrs.xml
<attr name="sourceType" format="enum">
<enum name="generic" value="1" />
<enum name="dash" value="2" />
<enum name="smooth_streaming" value="3" />
<enum name="hls" value="4" />
</attr>
SourceType.java
public enum SourceType {
Generic (1), DASH (2), SmoothStreaming (3), HLS (4);
private int value;
private SourceType(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public static SourceType fromInt(int value) {
switch (value) {
case 1: return Generic;
case 2: return DASH;
case 3: return SmoothStremaing;
case 4: return HLS;
default: throw new Error("Invalid SourceType");
}
}
}
BFPlayer.java
public BFPlayer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.BFPlayer);
// Clearly wrong:
// 1. SourceType.Generic cannot be cast to int
// 2. int cannot be cast to SourceType
SourceType sourceType = SourceType.fromInt(
attributes.getInt(R.styleable.BFPlayer_sourceType, SourceType.Generic.getValue())
);
}
但是,这感觉像是错误的解决方案:
.fromtInt
和 .getValue
来实例化新的SourceType 有更好的解决方案吗?
答案 0 :(得分:1)
枚举具有方法values()
,该方法返回该枚举类型的数组,每个枚举值都存在于该数组中。您可以将该枚举类型的静态数组定义为枚举的成员。
public enum SourceType {
Generic, DASH, SmoothStreaming, HLS;
static final SourceType values[] = SourceType.values();
}
然后可以实例化枚举对象,如下所示:
SourceType s = SourceType.values[someInt];
您当然可以通过简单地索引到SourceType.values()返回的数组来做到这一点,但这效率较低,因为它会为每个调用创建一个数组。我相信这可以解决您所有的三个问题:您不必使用任何其他方法来实例化SourceType;添加新值时,您无需手动更新数组。并且您不会随意将整数值分配给枚举选项。
答案 1 :(得分:1)
要解决您的问题“如果添加新值,则需要更新switch语句”,您可以使用以下
public enum SourceType {
// ...
private static final List<SourceType> SOURCE_TYPES_ = Arrays.asList(SourceType.values());
public static Optional<SourceType> find(int value) {
return SOURCE_TYPES_
.stream()
.filter(type -> value == type.getValue())
.findFirst();
}
}