使用数组引用作为自定义 Android 视图的 XML 属性

发布于 2024-12-12 08:26:28 字数 1111 浏览 0 评论 0原文

这个问题已经解决了,详情见评论。

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

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

我可以使用数组资源来设置 android Spinner 类的“entries”属性,没有错误,所以这似乎是我的实现中的问题。 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" />

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

This problem has been solved, see comments for details.

I am extending an existing Android View and loading some custom attributes, as described in Declaring a custom android UI element using XML and Defining custom attrs.

Attributes with boolean and integer formats work fine, but when I try to specify a reference to an array resource, the application crashes at launch. I have defined an integer array inside an xml resource file and I'm trying to use it as an attribute for the custom view.

I can use the array resource to set the "entries" attribute of the android Spinner class with no errors, so it seems to be a problem in my implementation. The logcat messages don't seem to supply any specific information about the crash, but I'm still looking so I will update if I find something.

The attributes are declared by (in attrs.xml):

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

The array is defined as (in arrays.xml):

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

And I am referencing the array by:

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

And this causes the application to crash immediately. In addition, if I reference a color resource instead of an array then the application does not crash. Does anybody know how to deal with this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

嘿看小鸭子会跑 2024-12-19 08:26:28

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

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

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

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

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

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 布局文件时,使用 code> 属性。示例:

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

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

Just going to piggyback off your question here, since your post shows up first if you google something like "array reference XML attribute custom view", so someone might find this helpful.

If you want your custom view to reference an array of strings, you can use Android's existing android:entries XML attribute, instead of creating a totally new custom attribute.

Just do the following in res/values/attrs.xml:

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

Then do this in your custom View's constructor:

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();
    }
}

And then you should be able to reference a string array via the android:entries attribute when you add your custom View to an XML layout file. Example:

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

This is exactly how it is done in the ListView class (look in the source, you'll see).

放肆 2024-12-19 08:26:28

另一个答案适用于字符串数组。但是,引用数组上的 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();

The other answer works well with array of strings. However, arr.getTextArray(...) on array of references, e.g.

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

will give you res/drawable/a.png as the CharSequence instead of the resource id.

The proper way to parse an array of references is this:

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();
情话已封尘 2024-12-19 08:26:28

问题是关于获取一个整数数组,对于我的情况,我需要从数组中读取自定义视图的颜色(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();

这是颜色数组的打印:

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

希望这会对一些人有所帮助。

The question is about obtain an integer array, for my case, I need to read the colors(int) from an array for my custom view, styeable definition as below:

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

Then I use my custom view like below:

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

The colors definition is as below:

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

So I need to obtain the colors in my custom view (ColorPickerView), code as below:

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();

Here is the print of 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

Hope this will help some guys.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文