Android:可以在可绘制select器中使用string/枚举吗?

问题

Q1 :有没有人设法在xmlselect器中使用自定义string/枚举属性? 我得到了一个布尔属性,遵循[1],但不是一个string属性。

编辑:感谢您的答案。 目前android只支持布尔select器。 查看接受的答案的原因。

我打算实现一个复杂的自定义button,其外观取决于两个variables。 其他将是布尔属性(true或false)和另一个类别属性(有许多不同的可能值)。 我的计划是使用布尔和string(或者也许枚举?)属性。 我希望我可以使用布尔和string属性在xmlselect器中定义UI。

Q2 :为什么在[1] onCreateDrawableState()中,布尔属性只有在它们是真的时才合并?

这是我testing,布尔属性工作,string不

:这只是一个testing应用程序来弄清楚,如果string/枚举属性是可能的xmlselect器。 我知道我可以设置button的textcolor没有自定义属性。

在我的演示应用程序中,我使用布尔属性将button背景设置为dark / bright和string属性来设置文本颜色,{“red”,“green”,“blue”}之一。 属性在/res/values/attrs.xml中定义

 <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MyCustomButton"> <attr name="make_dark_background" format="boolean" /> <attr name="str_attr" format="string" /> </declare-styleable> </resources> 

这里是我想要实现的select器:

@ drawable / custom_button_background(其中的作品)

 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/com.example.customstringattribute"> <item app:make_dark_background="true" android:drawable="@color/dark" /> <item android:drawable="@color/bright" /> </selector> 

@ color / custom_button_text_color(不起作用)

 <selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/com.example.customstringattribute"> <item app:str_attr="red" android:color="@color/red" /> <item app:str_attr="green" android:color="@color/green" /> <item app:str_attr="blue" android:color="@color/blue" /> <item android:color="@color/grey" /> </selector> 

这里是自定义button背景如何连接到布尔select器,文本颜色连接到stringselect器。

 <com.example.customstringattribute.MyCustomButton ... android:background="@drawable/custom_button_background" android:textColor="@color/custom_button_text_color" ... /> 

以下是如何在init()方法中加载属性:

 private void init(AttributeSet attrs) { TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MyCustomButton); final int N = a.getIndexCount(); for (int i = 0; i < N; ++i) { int attr = a.getIndex(i); switch (attr) { case R.styleable.MyCustomButton_str_attr: mStrAttr = a.getString(attr); break; case R.styleable.MyCustomButton_make_dark_background: mMakeDarkBg = a.getBoolean(attr, false); break; } } a.recycle(); } 

我有属性的int []数组

 private static final int[] MAKE_DARK_BG_SET = { R.attr.make_dark_background }; private static final int[] STR_ATTR_ID = { R.attr.str_attr }; 

而那些int []数组被合并为drawable状态

 @Override protected int[] onCreateDrawableState(int extraSpace) { Log.i(TAG, "onCreateDrawableState()"); final int[] drawableState = super.onCreateDrawableState(extraSpace + 2); if(mMakeDarkBg){ mergeDrawableStates(drawableState, MAKE_DARK_BG_SET); } mergeDrawableStates(drawableState, STR_ATTR_ID); return drawableState; } 

我也有我的属性设置方法refreshDrawableState():

 public void setMakeDarkBg(boolean makeDarkBg) { if(mMakeDarkBg != makeDarkBg){ mMakeDarkBg = makeDarkBg; refreshDrawableState(); } } public void setStrAttr(String str) { if(mStrAttr != str){ mStrAttr = str; refreshDrawableState(); } } 

[1]: 如何添加自定义button状态

Solutions Collecting From Web of "Android:可以在可绘制select器中使用string/枚举吗?"

Q1:

当您打开StateListDrawable.java的源代码时,您可以在读取可绘制的xmlselect器的inflate方法中看到这段代码: https : //android.googlesource.com/platform/frameworks/base/+/refs/头/主/graphics/ JAVA /机器人/graphics/抽拉/ StateListDrawable.java

  ... for (i = 0; i < numAttrs; i++) { final int stateResId = attrs.getAttributeNameResource(i); if (stateResId == 0) break; if (stateResId == com.android.internal.R.attr.drawable) { drawableRes = attrs.getAttributeResourceValue(i, 0); } else { states[j++] = attrs.getAttributeBooleanValue(i, false) ? stateResId : -stateResId; } } ... 

attrs<selector>中每个<item>元素的属性。

在这个for-loop中,它得到了android:drawable ,各种android:state_xxxx和自定义app:xxxx属性。 除了android:drawable属性之外的所有东西都只被解释为布尔值: attrs.getAttributeBooleanValue(....)被调用。

我认为这是基于源代码的答案:

您只能将自定义布尔属性添加到您的XML,而不是任何其他types(包括枚举)。

Q2:

我不确定为什么只有在专门设置为true的情况下才能合并状态。 我会怀疑代码应该看起来像这样:

 private static final int[] MAKE_DARK_BG_SET = { R.attr.make_dark_background }; private static final int[] NOT_MAKE_DARK_BG_SET = { -R.attr.make_dark_background }; .... .... @Override protected int[] onCreateDrawableState(int extraSpace) { Log.i(TAG, "onCreateDrawableState()"); final int[] drawableState = super.onCreateDrawableState(extraSpace + 2); mergeDrawableStates(drawableState, mMakeDarkBg? MAKE_DARK_BG_SET : NOT_MAKE_DARK_BG_SET); //mergeDrawableStates(drawableState, STR_ATTR_ID); return drawableState; } 

Q1:

我没有尝试过,但是:

你有没有尝试把你的@color/custom_button_text_color.xml放在drawable文件夹中? (可以肯定的是,Android中有一些文件夹魔法,我不确定这一点。)

Q2:

有两种用于状态集的用例。 一个是以编程方式显式声明select器的状态画图。 在这种情况下,对于select器,如果没有设置属性,则需要能够告诉Android 使用此drawable。 为了expression这一点,可以在int[]包含否定标准(以负号开头)。

虽然这在select器标准的上下文中几乎没有提及,但从来没有提到可绘制状态本身(也就是可绘制状态的表示)。 所以如果一个不包含否定的状态ID,肯定是安全的。 提供的Android实现也不包括它们。

抱歉,您无法在xml中创build自定义绘图: https : //groups.google.com/d/msg/android-developers/glpdi0AdMzI/LpW4HGMB3VIJ