34

此问题已解决,详情见评论。

我正在扩展现有的 Android 视图并加载一些自定义属性,如使用 XML 声明自定义 android UI 元素定义自定义属性中所述。

布尔和整数格式的属性可以正常工作,但是当我尝试指定对数组资源的引用时,应用程序在启动时崩溃。我在 xml 资源文件中定义了一个整数数组,并尝试将其用作自定义视图的属性。

我可以使用数组资源来设置 android Spinner 类的“条目”属性而没有错误,所以这似乎是我的实现中的一个问题。logcat 消息似乎没有提供有关崩溃的任何具体信息,但我仍在寻找,所以如果我发现了什么,我会更新。

属性由(在 attrs.xml 中)声明:

<declare-styleable name="CustomView">
    <attr name="values" format="reference"/>
    <attr name="isActive" format="boolean"/>
</declare-styleable>

数组定义为(在arrays.xml 中):

<integer-array name="nums">
    <item>1</item>
    <item>2</item>
    <item>3</item>
</integer-array>

我通过以下方式引用数组:

<com.test.CustomView cv:values="@array/nums" />

这会导致应用程序立即崩溃。此外,如果我引用颜色资源而不是数组,则应用程序不会崩溃。有谁知道如何处理这个问题?

4

3 回答 3

50

只是在这里捎带你的问题,因为如果你用谷歌搜索“数组引用 XML 属性自定义视图”之类的东西,你的帖子首先会出现,所以有人可能会觉得这很有帮助。

如果您希望您的自定义视图引用一个字符串数组,您可以使用 Android 现有的android:entriesXML 属性,而不是创建一个全新的自定义属性。

只需执行以下操作res/values/attrs.xml

<resources>
    <declare-styleable name="MyCustomView">
        <attr name="android:entries" />
    </declare-styleable>
</resources>

然后在您的自定义视图的构造函数中执行此操作:

public MyCustomView(Context context, AttributeSet attrs, int defStyle)
{
    super(context, attrs, defStyle);

    TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MyCustomView, defStyle, 0);
    try
    {
        CharSequence[] entries = a.getTextArray(R.styleable.MyCustomView_android_entries);
        if (entries != null)
        {
           //do something with the array if you want
        }
    }
    finally
    {
        a.recycle();
    }
}

android:entries然后,当您将自定义视图添加到 XML 布局文件时,您应该能够通过属性引用字符串数组。例子:

<com.example.myapp.MyCustomView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:entries="@array/my_array_of_strings" />

这正是它在ListView类中完成的方式(查看源代码,您会看到)。

于 2013-01-03T17:56:13.740 回答
19

另一个答案适用于字符串数组。但是,arr.getTextArray(...)引用数组上,例如

<array name="tmp">
  <item>@drawable/a</item>
  <item>@drawable/b</item>
</array>

会给你res/drawable/a.png作为 CharSequence 而不是资源 id。

解析引用数组的正确方法是:

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomView);

int arrayResourceId = typedArray.getResourceId(R.styleable.CustomView_CustomAttr, 0);
if (arrayResourceId != 0) {
    final TypedArray resourceArray = getResources().obtainTypedArray(arrayResourceId);
    for (int i = 0; i < resourceArray.length(); i++) {
        final int resourceId = resourceArray.getResourceId(i, 0);

        // do stuff with resourceId, such as getResources().getDrawable(resourceId)
    }
    resourceArray.recycle();
}
typedArray.recycle();
于 2016-06-03T07:19:10.657 回答
9

问题是关于获取一个整数数组,就我而言,我需要从数组中读取颜色(int)以用于我的自定义视图,样式定义如下:

<declare-styleable name="ColorPickerView">
        <attr name="colors" format="reference" />
    </declare-styleable>

然后我使用我的自定义视图,如下所示:

<com.rainliu.colorpicker.ColorPickerView
    android:id="@+id/rtePalette"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    colorPickerView:colors="@array/colorPickerColors"
    />

颜色定义如下:

<resources>
    <color name="colorPrimary">#FF9800</color>
    <array name="colorPickerColors">
        <item>#000000</item>
        <item>#E65100</item>
        <item>@color/colorPrimary</item>
    </array>
</resources>

所以我需要在我的自定义视图(ColorPickerView)中获取颜色,代码如下:

TypedArray ta = context.obtainStyledAttributes(attributeSet, R.styleable.ColorPickerView);
int colorsId = ta.getResourceId(R.styleable.ColorPickerView_colors, 0);
int[] colorsArray = ta.getResources().getIntArray(colorsId);
for (int a : colorsArray) {
  Log.e("AA", "color == " + a);
}
ta.recycle();

这是colorsArray的打印:

03-11 14:25:53.894 15300-15300/com.chinalwb.are E/AA: color == -16777216
03-11 14:25:53.894 15300-15300/com.chinalwb.are E/AA: color == -1683200
03-11 14:25:53.894 15300-15300/com.chinalwb.are E/AA: color == -1683200

希望这会帮助一些人。

于 2018-03-11T06:43:21.617 回答