我在解析自定义属性时遇到了一些奇怪的事情。假设我的解析器看起来像这样:
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();
这行得通。现在,如果我用 final int size = attributes.length();
替换第 2 行,这意味着我得到了这个:
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()
不仅仅是返回数组中具有数据的索引数
。这两种方法之间到底有什么区别,一种方法允许我获取属性,而另一种方法不允许?
最佳答案
我只是在摆弄这个,我发现整个事情很困惑,但我想我明白了:
所以您已经在attrs.xml 中为您的类声明了N 个属性。
现在得到的 TypedArray
的大小是 N。它总是传递相同大小的数组。
但也许您在布局 xml 中只定义了 X 个属性,所以 getIndexCount()
返回 X。
在你的小部件的初始化中,如果你问自己有多少属性和哪些属性
在 xml 中定义,您首先会使用 getIndexCount()
找出有多少。
然后你从 0 循环到 getIndexCount()-1
并询问 TypedArray
:“什么是索引
第 i 个 supplied 属性?”。
所以假设你想强制在 xml 中设置一个属性,你现在可以检查这个 因为对 getIndex() 的调用之一必须返回您要查找的 ID。
但您始终可以忽略它,并提供默认值。然后你可以调用 a.getInteger( R.styleable.MyClass_MyAttribute, defaultValue );
您可以检查 R.java 以查看每个类的所有属性 ID 都从 0 开始。生成的评论也有助于理解。
关于android - TypedArray 和 styleable 属性 : getIndexCount() vs. length(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8405430/