TypedArray和设置样式属性:getIndexCount()与长() [英] TypedArray and styleable attributes: getIndexCount() vs. length()

查看:1788
本文介绍了TypedArray和设置样式属性:getIndexCount()与长()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我和解析自定义属性的工作,和我遇到一些奇怪的。比方说,我的解析器看起来是这样的:

 最后TypedArray属性= context.obtainStyledAttributes(ATTRS,R.styleable.Item);
最终诠释大小= attributes.getIndexCount();的for(int i = 0; I<大小;我++){
   最终诠释ATTR = attributes.getIndex(I)
   如果(ATTR == R.styleable.Item_custom_attrib){
      最终诠释RESOURCEID = attributes.getResourceId(ATTR,-1);
      如果(RESOURCEID == -1)
         抛出新Resources.NotFoundException(指定的资源没有被发现。);
...
}
attributes.recycle();

这工作。现在,如果我取代线#2 最终诠释大小= attributes.length(); 这意味着我得到这样的:

 最后TypedArray属性= context.obtainStyledAttributes(ATTRS,R.styleable.Item);
最终诠释大小= attributes.length();的for(int i = 0; I<大小;我++){
   最终诠释ATTR = attributes.getIndex(I)
   如果(ATTR == R.styleable.Item_animation_src){
      最终诠释RESOURCEID = attributes.getResourceId(ATTR,-1);
      如果(RESOURCEID == -1)
         抛出新Resources.NotFoundException(指定的资源没有被发现。);
...
}
attributes.recycle();

这崩溃与我扔Resources.NotFoundException。换句话说, attributes.getResourceId(ATTR,-1); 返回默认 1

现在,在这种特定的情况下,仅存在一个自定义属性。无论 attributes.getIndexCount() attributes.length() 1的回报,因为确实是我的属性的值。这意味着 getIndex(我)应返回相同的号码,但事实并非如此。它意味着 getIndexCount()确实不是简单地返回有数据数组中的索引的数量多。究竟什么是两种方法之间的差异,其中一个可以让我获得的属性,而其他不?


解决方案

我只是用这个摆弄,我发现整个事情混乱,但我想我想通了:

所以,你已经宣布N的属性的 attrs.xml ,为你的类。
现在所获得的 TypedArray 是N.它总是在传递相同大小的数组的大小。

但是,也许你定义只适用于X属性在布局XML ,所以 getIndexCount()返回x

在你的widget的初始化,如果你要问自己有多少,哪些属性
在XML中定义,你会先找出有多少,使用 getIndexCount()
然后你从环路0至getIndexCount() - 1 ,并要求 TypedArray :什么是指数
第i个的提供的属性?

因此​​,假设你想强制某个属性的XML来进行设置,你现在可以检查此
因为调用getIndex()中的一个必须返回你正在寻找的ID。

但你总是可以忽略,并且提供缺省值。然后,你可以叫 a.getInteger(R.styleable.MyClass_MyAttribute,设置defaultValue);

您可以检查R.java地看到,所有的属性ID从0开始,每类。生成的评论也有助于理解。

I'm working with parsing custom attributes, and I've come across something weird. Let's say my parser looks something like this:

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

This works. Now, if I replace line #2 with final int size = attributes.length(); which means I get this:

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

This crashes with the Resources.NotFoundException that I throw. In other words, attributes.getResourceId(attr, -1); returns the default -1 value.

Now, in this particular case, there is only one custom attribute. Both attributes.getIndexCount() and attributes.length() return 1 because there is indeed a value in my attribute. Which means getIndex(i) should return the same number, but it does not. It implies that getIndexCount() does more than simply return the number of indices in the array that have data. What exactly is the difference between the two methods where one allows me to get the attributes while the other does not?

解决方案

I was just fiddling with this and I found the whole thing confusing, but I think I got it figured out:

So you have declared N attributes in attrs.xml, for your class. Now the size of the obtained TypedArray is N. It always passes the same sized array.

But maybe you defined only X attributes in your layout xml, so getIndexCount() returns X.

In your widget's init, if you were to ask yourself how many and which attributes were defined in xml, you would first find out how many, using getIndexCount(). Then you loop from 0 to getIndexCount()-1 and ask the TypedArray: "what's the index of the i-th supplied attribute?".

So suppose you want to force an attribute to be set in xml, you can now check this because one of the calls to getIndex() has to return the id you are looking for.

But you can always ignore that, and supply default values. Then you can just call a.getInteger( R.styleable.MyClass_MyAttribute, defaultValue );

You can check R.java to see that all attribute IDs start at 0, for every class. The generated comments are also helpful to understand.

这篇关于TypedArray和设置样式属性:getIndexCount()与长()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆