Android库中的属性名称是否需要加前缀?

时间:2017-07-06 01:55:08

标签: android xml

我已经阅读(并通过测试确认)资源值名称(字符串,Drawables,维度等)应该在开头有一个前缀(通常是库的名称)以避免名称冲突,因为使用的项目库和声明具有匹配名称的资源将覆盖库的资源。

我不清楚的是attr内的<declare-styleable>属性的名称是否也应该加上前缀。由于它们被包裹在<declare-styleable>中,它们是否可以防止过度写入?在Java代码中,它们的资源名称自动以<declare-styleable>的名称为前缀,但在XML文件中使用时,它们不是。{/ p>

我猜他们的用法是上下文敏感的。在我的自定义Preference代码中,当我使用特定样式调用context.obtainStyledAttributes()时,只有在那时才将XML属性解释为特定类型。如果我声明类型为"min"的名为float的Preference可设置属性并在我的项目中使用它,那么在v7.preference库的SeekBarPreference样式中有一个名为"min"的属性并不重要类型为int,因为SeekBar在调用obtainStyledAttributes()时不使用我的样式。

因此,如果我的假设是正确的,那么编译器就没有理由按名称合并属性。但自定义属性样式在Android中是一个复杂的野兽,我不确定我在测试中是否遗漏了一些东西。为了便于使用/记录,省略我的库的属性名称中的前缀会很好。

如果<declare-styleable>定义了Style的属性,那么我认为它仍然可以安全地避免冲突,因为Styles不会合并。他们只从自己的属性中互相引用。如果我理解正确 - 他们对我来说有些尴尬。

在相关的说明中,是否有任何理由应该为视图ID添加前缀?我想是的,因为我的库视图存在于项目的视图结构中,并且库的用户在与我的一个匹配的ID上调用findViewById(),我可以设想搜索首先显示我的视图的情况绊倒他们。但谷歌自己的appcompat库没有采取这样的预防措施,所以我不确定。

1 个答案:

答案 0 :(得分:1)

在研究了文档和AOSP源代码之后,我得出的结论是,你应该添加属性名称。

资源属性不是<declare-styleable>本地的。它们都是全球性的。当您声明资源属性(可以在<declare-styleable>内部或外部完成)时,您可以为其命名并为其指定格式类型:

<attr name="my_attribute" format="string" /> <!-- This is a declaration -->

当您引用资源属性(仅在<declare-styleable>内)时,您列出其名称但不列出其格式。

<attr name="my_attribute" /> <!-- This is a reference -->
如果您尝试声明两个具有相同名称的属性,则

Lint会显示错误。

您可以在<declare-styleable>范围内声明属性,这仅仅是为了简化代码的简便性。它并不意味着范围有限。如果您计划在多个样式中使用相同的属性,那么将其声明置于任何<declare-styleable>之外可能是一种好习惯,因此可以轻松找到它。

我注意到的一个奇怪的是,如果两个不同的库具有重叠的属性声明,Lint不会显示错误。我想如果它们都具有相同的格式类型,那么它不会引起问题。我还没有检查过,如果他们不知道会发生什么。

至于为什么Google没有在AppCompat中添加前缀属性名称,我认为他们希望它非常易于使用,并且几乎可以与AOSP xml代码互换,因此他们希望属性名称与AOSP。因此他们认为使用的简单性超过了风险。我怀疑他们忽略的是他们在设置和使用样式和属性时是如何脱节和缺乏文档的,所以在设置我们自己的自定义视图和首选项时要注意什么并不明显。