Использование ссылки на массив в качестве атрибута XML для пользовательского представления Android

Эта проблема решена, подробности см. В комментариях.

Я расширяю существующее представление Android и загружаю некоторые настраиваемые атрибуты, как описано в Объявление настраиваемого элемента пользовательского интерфейса Android с помощью XML и Определение настраиваемых атрибутов.

Атрибуты с логическим и целочисленным форматами работают нормально, но когда я пытаюсь указать ссылку на ресурс массива, приложение вылетает при запуске. Я определил целочисленный массив внутри файла ресурсов xml и пытаюсь использовать его в качестве атрибута для настраиваемого представления.

Я могу использовать ресурс массива для установки атрибута "entry" класса android Spinner без ошибок, поэтому, похоже, это проблема в моей реализации. Сообщения logcat, похоже, не содержат какой-либо конкретной информации о сбое, но я все еще ищу, поэтому я обновлю, если что-то найду.

Атрибуты объявлены (в attrs.xml):

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

Массив определяется как (в array.xml):

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

И я ссылаюсь на массив:

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

И это сразу вызывает сбой приложения. Кроме того, если я буду ссылаться на ресурс цвета, а не на массив, приложение не выйдет из строя. Кто-нибудь знает, как решить эту проблему?


person Michael    schedule 30.10.2011    source источник
comment
Эта проблема решена, это была ошибка в способе загрузки атрибутов в конструктор класса. Раньше я использовал метод getInt () для TypedArray, когда мне следовало использовать getResourceId () со справочным форматом.   -  person Michael    schedule 30.10.2011


Ответы (3)


Я просто собираюсь ответить на свой вопрос здесь, поскольку ваше сообщение появляется первым, если вы используете Google что-то вроде "настраиваемое представление 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. Пример:

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

Именно так это и делается в классе ListView (см. в источнике вы увидите).

person XåpplI'-I0llwlg'I -    schedule 03.01.2013
comment
Я хочу передать выводимый массив в качестве аргументов ... любая помощь по этому поводу - person Dominic D'Souza; 09.10.2015

Другой ответ хорошо работает с массивом строк. Однако arr.getTextArray(...) в массиве ссылок, например

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

предоставит вам res/drawable/a.png в качестве CharSequence вместо идентификатора ресурса.

Правильный способ синтаксического анализа массива ссылок таков:

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();
person Jin    schedule 03.06.2016
comment
На какую переменную RES вы здесь ссылаетесь res.obtainTypedArray (arrayResourceId); ? - person Rich Morey; 10.08.2017
comment
res - это просто ресурсы, например context.getResources () - person Jin; 12.08.2017

Вопрос в том, чтобы получить целочисленный массив, в моем случае мне нужно прочитать цвета (int) из массива для моего пользовательского представления, определение styeable, как показано ниже:

<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

Надеюсь, это поможет некоторым ребятам.

person LiuWenbin_NO.    schedule 11.03.2018
comment
Это отлично работает для получения массива цветовых ресурсов. - person Harihar Das; 31.07.2018