TypedArray и styleable атрибуты: getIndexCount () против длины () - PullRequest
1 голос
/ 06 декабря 2011

Я работаю с парсингом пользовательских атрибутов и наткнулся на что-то странное. Допустим, мой парсер выглядит примерно так:

final TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.Item);
final int size = attributes.getIndexCount();

for(int i = 0; i < size; i++) {
   final int attr = attributes.getIndex(i);
   if(attr == R.styleable.Item_custom_attrib) {
      final int resourceId = attributes.getResourceId(attr, -1);
      if(resourceId == -1)
         throw new Resources.NotFoundException("The resource specified was not found.");
...
}
attributes.recycle();

Это работает. Теперь, если я заменю строку # 2 на final int size = attributes.length();, что означает, что я получу это:

final TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.Item);
final int size = attributes.length();

for(int i = 0; i < size; i++) {
   final int attr = attributes.getIndex(i);
   if(attr == R.styleable.Item_animation_src) {
      final int resourceId = attributes.getResourceId(attr, -1);
      if(resourceId == -1)
         throw new Resources.NotFoundException("The resource specified was not found.");
...
}
attributes.recycle();

Это происходит с ошибкой Resources.NotFoundException, которую я выбрасываю. Другими словами, attributes.getResourceId(attr, -1); возвращает значение по умолчанию -1.

Теперь, в данном конкретном случае, есть только один настраиваемый атрибут. И attributes.getIndexCount(), и attributes.length() возвращают 1, потому что в моем атрибуте действительно есть значение. Это означает, что getIndex(i) должен возвращать тот же номер, но это не так. Это означает, что getIndexCount() делает больше, чем просто return the number of indices in the array that have data. В чем разница между этими двумя методами, когда один позволяет мне получить атрибуты, а другой нет?

Ответы [ 2 ]

4 голосов
/ 12 января 2012

Я просто возился с этим и обнаружил, что все это сбивает с толку, но, думаю, я понял это:

Итак, вы объявили N атрибутов в attrs.xml для вашего класса. Теперь размер полученного TypedArray равен N. Он всегда проходит массив одинакового размера.

Но, возможно, вы определили только X атрибутов в вашем формате xml , поэтому getIndexCount() возвращает X.

В инициализации вашего виджета, если бы вы спросили себя, сколько и какие атрибуты были определены в XML, вы сначала узнаете, сколько, используя getIndexCount(). Затем вы выполняете цикл с 0 to getIndexCount()-1 и спрашиваете TypedArray: «Каков индекс i-й предоставленный атрибут ? ".

Итак, предположим, что вы хотите принудительно установить атрибут в xml, теперь вы можете проверить это потому что один из вызовов getIndex () должен вернуть искомый идентификатор.

Но вы всегда можете игнорировать это и указывать значения по умолчанию. Тогда вы можете просто позвонить a.getInteger( R.styleable.MyClass_MyAttribute, defaultValue );

Вы можете проверить R.java, чтобы увидеть, что все идентификаторы атрибутов начинаются с 0 для каждого класса. Сгенерированные комментарии также полезны для понимания.

2 голосов
/ 22 августа 2012

Ваш вопрос очень прост, он широко используется, например, сначала он определяет класс myview extends View {...}, а затем применяет myview к layout.xml и определяет некоторые атрибуты, например 'textColor = "# ffffffff" и т.д., в layout.xml, так что ваш a.getIndexCount () возвращает не ноль или не ноль, это то, что вы ожидали.

теперь я изменяю вопрос, вы определяете класс myview расширяет Object, примечание не расширяет класс View, и вы никогда не будете использовать layout.xml для своего самоопределенного myview.все такие вещи, как определенный в Android класс View реализует Drawable.Callback, Drawable.Callback2, KeyEvent.Callback, AccessibilityEventSource {...}, без layout.xml, без расширений. Удобство просмотра только ресурсы, которые вы можете использовать, - это attrs.xml, styles.xml.

так что вы можете сделать, чтобы a.getIndexCount () возвращал не ноль или не ноль как mytop: почему TypedArray.getIndexCount () всегда возвращает 0

...