我有一个很大的Android代码库,我正在编写一个自定义lint规则,用于检查某些属性的值是否在给定范围内。
例如,我有这个组件:
<MyCustomComponent
my:animation_factor="0.7"
...>
</MyCustomComponent>
我想编写一个lint规则,提醒开发人员谨慎使用my:animation_factor
&gt; = 1的值。
我按照http://tools.android.com/tips/lint-custom-rules上的说明操作,并设法使用以下代码检索my:animation_factor
的值:
import com.android.tools.lint.detector.api.*;
public class XmlInterpolatorFactorTooHighDetector {
....
@Override
public Collection<String> getApplicableElements() {
return ImmutableList.of("MyCustomComponent");
}
@Override
public void visitElement(XmlContext context, Element element) {
String factor = element.getAttribute("my:animation_factor");
...
if (value.startsWith("@dimen/")) {
// How do I resolve @dimen/xyz to 1.85?
} else {
String value = Float.parseFloat(factor);
}
}
}
当my:animation_factor
等属性具有文字值(例如0.7
)时,此代码可以正常工作。
但是,当属性值是资源(例如@dimen/standard_anim_factor
)时,element.getAttribute(...)
会返回属性的字符串值,而不是实际解析的值。
例如,当我的MyCustomComponent
看起来像这样:
<MyCustomComponent
my:animation_factor="@dimen/standard_anim_factory"
...>
</MyCustomComponent>
和@dimen/standard_anim_factor
在别处定义:
<dimen name="standard_anim_factor">1.85</dimen>
然后字符串factor
变为&#34; @ dimen / standard_anim_factor&#34;而不是&#34; 1.85&#34;。
有没有办法解决&#34; @ dimen / standard_anim_factor&#34;处理MyCustomComponent
元素时,资源的实际价值(即&#34; 1.85&#34;)?
答案 0 :(得分:0)
我相信您正在寻找getResources().getDimension()
。
来源:http://developer.android.com/reference/android/content/res/Resources.html#getDimension%28int%29
答案 1 :(得分:0)
在解析数据后假设xml节点,请尝试以下
Element element = null; //It is your root node.
NamedNodeMap attrib = (NamedNodeMap) element;
int numAttrs = attrib.getLength ();
for (int i = 0; i < numAttrs; i++) {
Attr attr = (Attr) attrib.item (i);
String attrName = attr.getNodeName ();
String attrValue = attr.getNodeValue ();
System.out.println ("Found attribute: " + attrName + " with value: " + attrValue);
}
答案 2 :(得分:0)
值解析的一般问题是,它们取决于您所在的Android运行时上下文。可能有几个values
个文件夹具有不同的具体值,用于您的键@dimen/standard_anim_factory
,所以你知道的。
尽管如此,AFAIK存在两种选择:
执行两阶段检测:
Detector.afterProjectCheck
并通过迭代第1阶段中填写的两个列表来解析您的属性通常LintUtils
类[1]是这个东西的最佳位置,但不幸的是没有解决尺寸值的方法。但是,有一个名为getStyleAttributes
的方法,它演示了如何解析资源值。因此,您可以编写自己的方便方法来解析维值:
private int resolveDimensionValue(String name, Context context){
LintClient client = context.getDriver().getClient();
LintProject project = context.getDriver().getProject();
AbstractResourceRepository resources = client.getProjectResources(project, true);
return Integer.valueOf(resources.getResourceItem(ResourceType.DIMEN, name).get(0).getResourceValue(false).getValue());
}
注意:我还没有测试过上面的代码。所以请将其视为理论建议: - )
对于您的自定义Lint规则代码,还有一点建议,因为您只对该属性感兴趣:
而不是在visitElement
中执行类似的操作:
String factor = element.getAttribute("my:animation_factor");
......你可能想做这样的事情:
@Override
public Collection<String> getApplicableAttributes() {
return ImmutableList.of("my:animation_factor");
}
@Override
void visitAttribute(@NonNull XmlContext context, @NonNull Attr attribute){
...
}
但这只是一个偏好问题: - )