TypedArray和可设置样式的属性:getIndexCount()vs.length()

Dee*_*eeV 1 android custom-attributes

我正在解析自定义属性,遇到了一些奇怪的事情。假设我的解析器看起来像这样:

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();
Run Code Online (Sandbox Code Playgroud)

这可行。现在,如果我将第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();
Run Code Online (Sandbox Code Playgroud)

这与我抛出的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。这两种方法之间到底有什么区别,一种允许我获取属性,而另一种不允许我获取属性?

xor*_*ate 5

我只是在摆弄这个,发现整个过程令人困惑,但是我想我已经弄明白了:

因此,您已在attrs.xml中为类声明了N个属性。现在,获得的大小TypedArray为N。它始终传递相同大小的数组。

但是也许您仅在布局xml中定义了X个属性,所以getIndexCount()返回X。

在小部件的初始化中,如果要问自己在xml中定义了多少个属性以及定义了哪些属性,则首先要使用来查找多少个getIndexCount()。然后,您循环0 to getIndexCount()-1询问TypedArray:“第i个提供的属性的索引是什么?”。

因此,假设您要强制在xml中设置属性,现在可以检查此内容,因为对getIndex()的调用之一必须返回您要查找的ID。

但是您始终可以忽略它,并提供默认值。那你就可以打电话a.getInteger( R.styleable.MyClass_MyAttribute, defaultValue );

您可以检查R.java以查看每个类的所有属性ID均从0开始。生成的注释也有助于理解。