关于declare-styleable
标签的珍贵文档很少,我们可以通过它来声明组件的自定义样式。我确实找到format
标记的attr
属性的有效值this list。虽然这很好,但它没有解释如何使用其中的一些值。浏览attr.xml(标准属性的Android源代码),我发现您可以执行以下操作:
<!-- The most prominent text color. -->
<attr name="textColorPrimary" format="reference|color" />
format
属性显然可以设置为值的组合。据推测,format
属性有助于解析器解释实际的样式值。然后我在attr.xml中发现了这个:
<!-- Default text typeface. -->
<attr name="typeface">
<enum name="normal" value="0" />
<enum name="sans" value="1" />
<enum name="serif" value="2" />
<enum name="monospace" value="3" />
</attr>
<!-- Default text typeface style. -->
<attr name="textStyle">
<flag name="normal" value="0" />
<flag name="bold" value="1" />
<flag name="italic" value="2" />
</attr>
这两个似乎都声明了一组指定样式的允许值。
所以我有两个问题:
enum
值之一的样式属性与可以采用一组flag
值的样式属性之间的区别是什么?declare-styleable
如何运作的更好的文档(除了逆向工程Android源代码)?答案 0 :(得分:69)
这里有一个问题:Defining custom attrs 一些信息,但不多。
这是post。它有关于标志和枚举的良好信息:
自定义XML属性标志
标志是特殊的属性类型 他们只被允许了 值的一小部分,即那些 在下面定义的 属性标签。标志由。指定 “名称”属性和“值” 属性。这些名字是必需的 在该属性类型中是唯一的 但价值观不一定是。这是 进化过程中的原因 我们拥有的Android平台 “fill_parent”和“match_parent”都是 映射到相同的行为。其 价值观相同。
name属性映射到名称 用在价值所在的地方 布局XML并不需要 命名空间前缀因此,对于 上面的“tilingMode”我选择了“中心”作为 属性值。我本可以有 就像容易选择“拉伸”或 “重复”但没有别的。不 甚至代替实际价值 本来可以的。
value属性必须是 整数。十六进制或。十六进制的选择 标准数字表示已启动 给你。里面有几个地方 两者都使用的Android代码 并且Android编译器很乐意 接受。
自定义XML属性枚举
枚举使用几乎完全相同 作为一个条款的标志的方式, 它们可以互换使用 整数。在引擎盖Enums和 整数映射到相同的数据 type,即Integer。什么时候 出现在属性定义中 使用整数,枚举可以防止 “神奇数字”总是很糟糕。 这就是为什么你可以拥有一个 “android:layout_width”与a 维,整数或命名字符串 “FILL_PARENT。”
要把它放到上下文中,让我们来吧 假设我创建了一个自定义 属性叫 “layout_scroll_height”接受 整数或字符串 “scroll_to_top。”为此,我要添加一个 “整数”格式属性并遵循 与enum:
<attr name="layout_scroll_height" format="integer"> <enum name="scroll_to_top" value="-1"/> </attr>
使用Enums时的一个规定 以这种方式是开发人员 使用您的自定义View可以 故意将值“-1”放入 布局参数。这个会 触发特殊情况逻辑 “scroll_to_top。”这样的意外(或 预期)行为可能很快 将你的图书馆归入“遗产” 代码“如果Enum值是桩的话 选择不好。
正如我所看到的,您可以在实际中为属性添加的真实值受限于您可以从中获得的内容。查看AttributeSet
课程参考here以获取更多提示。
您可以获得:
getAttributeBooleanValue
),getAttributeFloatValue
),getAttributeIntValue
),getAttributeUnsignedIntValue
),getAttributeValue
)答案 1 :(得分:63)
enum
和flag
之间的一个主要区别。前者用于我们选择一个,当我们为某个View分配相应的属性时,只选择一个值。但是,可以使用按位OR运算符组合后者的值。
一个例子,在res/values/attr.xml
<!-- declare myenum attribute -->
<attr name="myenum">
<enum name="zero" value="0" />
<enum name="one" value="1" />
<enum name="two" value="2" />
<enum name="three" value="3" />
</attr>
<!-- declare myflags attribute -->
<attr name="myflags">
<flag name="one" value="1" />
<flag name="two" value="2" />
<flag name="four" value="4" />
<flag name="eight" value="8" />
</attr>
<!-- declare our custom widget to be styleable by these attributes -->
<declare-styleable name="com.example.MyWidget">
<attr name="myenum" />
<attr name="myflags" />
</declare-styleable>
在res/layout/mylayout.xml
我们现在可以做
<com.example.MyWidget
myenum="two"
myflags="one|two"
... />
因此枚举选择其中一个可能的值,而标志可以组合。数值应该反映出这种差异,通常你会希望序列对于枚举(用作数组索引,比如说)和0,1,2,3,...
的标志去1,2,4,8,...
因此它们可以是独立的添加或删除,使用按位OR |
组合标记。
我们可以明确定义&#34;元标记&#34;值不是2的幂,因此引入了一种常见组合的简写。例如,如果我们在myflags
声明中包含此内容
<flag name="three" value="3" />
然后我们可以写myflags="three"
代替myflags="one|two"
,与3 == 1|2
完全相同。
就个人而言,我喜欢一直包括
<flag name="none" value="0" /> <!-- or "normal, "regular", and so on -->
<flag name="all" value="15" /> <!-- 15 == 1|2|4|8 -->
这将允许我立即取消设置或设置所有标志。
更巧妙的是,可能是另一个标志暗示了一个标志。因此,在我们的示例中,假设设置的eight
标志应该强制设置four
标志(如果它已经不存在)。然后,我们可以重新定义eight
以预先包含four
标志,
<flag name="eight" value="12" /> <!-- 12 == 8|4 -->
最后,如果要声明库项目中的属性但想要将它们应用于另一个项目的布局(依赖于lib),则需要使用必须在XML中绑定的命名空间前缀。根元素。如,
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:auto="http://schemas.android.com/apk/res-auto"
... >
<com.example.MyWidget
auto:myenum="two"
auto:myflags="one|two"
... />
</RelativeLayout>