我试图提取已在Activity中分配了id的所有TextView,以便用动态值填充它们。为此,我使用XMLResourceParser
浏览代码并获取ID。这是代码:
public int[] getElementIds(int layoutId, String viewType)
throws XmlPullParserException, IOException{
XmlResourceParser parser = activity.getResources().getLayout(layoutId);
LinkedList<Integer> idList = new LinkedList<Integer>();
while(parser.getEventType()!=XmlResourceParser.END_DOCUMENT){
parser.next();
if(parser.getEventType()==XmlResourceParser.START_TAG){
if(parser.getName().equals(viewType)){
idList.add(parser.getIdAttributeResourceValue(0)); //here's the problem
}
}
}
// returns an int[] from values collected
}
带注释的行只返回零,即我指定的默认值。但是,以下代码有效,属性索引通过反复试验得出:
idList.add(parser.getAttributeResourceValue(0, 1)); // the zero here is 'id' attribute index
有什么想法吗?
答案 0 :(得分:0)
经过额外的研究,似乎我在API中发现了一个错误。在线提供的代码如下所示:
public int getIdAttributeResourceValue(int defaultValue) {
return getAttributeResourceValue(null, "id", defaultValue);
}
public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) {
int idx = nativeGetAttributeIndex(mParseState, namespace, attribute);
if (idx >= 0) {
return getAttributeResourceValue(idx, defaultValue);
}
return defaultValue;
}
public int getAttributeResourceValue(int idx, int defaultValue) {
int t = nativeGetAttributeDataType(mParseState, idx);
// Note: don't attempt to convert any other types, because
// we want to count on appt doing the conversion for us.
if (t == TypedValue.TYPE_REFERENCE) {
return nativeGetAttributeData(mParseState, idx);
}
return defaultValue;
}
其中最后一个功能是实际完成工作的功能。这个类没有文档(XMLBlock),我无法访问实际用C编写的native
函数。我所知道的是这里的违规函数是第二个,带有命名空间和属性名称是参数。对于属性名称'style',它可以正常工作,但对于'id'(这是由另一个地方的API提供的名称,以及由返回属性名称的另一个函数返回的值,提供给定的索引),它不会什么都没有,并且一直吐出默认值。此外,我可以通过使用参数是属性索引而不是名称(上面复制的最后一个函数)的函数来访问那些相同的id值。结论:某些内容与“本机”代码处理名称“id”的方式混淆了。我正在向开源项目发送错误报告,我会发布任何回复。
答案 1 :(得分:0)
作为一种解决方法,我已经在我自己的代码中实现了这个功能:
private int getIdAttributeResourceValue(XmlResourceParser parser) {
final int DEFAULT_RETURN_VALUE = 0;
for (int i = 0; i < parser.getAttributeCount(); i++) {
String attrName = parser.getAttributeName(i);
if ("id".equalsIgnoreCase(attrName)) {
return parser.getAttributeResourceValue(i, DEFAULT_RETURN_VALUE);
}
}
return DEFAULT_RETURN_VALUE;
}