我认为将属性声明为可设置或不可设置之间只有以下区别。
在attrs.xml中,您可以声明自定义属性,直接在“resources”部分或“declare-styleable”内部声明:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="attrib1" format="string" />
<declare-styleable name="blahblah">
<attr name="attrib2" format="string" />
</declare-styleable>
现在我们将"attrib1"定义为非样式属性,而"attrib2"则为可样式化属性。
在layout/someactivity.xml
中,我们可以直接使用这些属性(无需命名空间):
<com.custom.ViewClass attrib1="xyz" attrib2="abc"/>
你可以在 style.xml
声明中使用 "attrib2" 这个 "styleable" 属性。同样,在这里不需要命名空间(即使在布局 XML 中使用了命名空间)。
<style name="customstyle" parent="@android:style/Widget.TextView">
<item name="attrib2">text value</item>
<item name="android:textColor">@color/white</item>
</style>
那么你也可以按样式设置属性。
<com.custom.CustomView attrib1="xyz" style="@style/customstyle"/>
假设我们这样做:我们直接在XML中设置attrib1
,并在样式中设置attrib2
。
我曾经看到过一些描述,它们声称"blahblah
"必须是使用这些属性的自定义视图类的名称,并且您需要使用命名空间来引用布局XML中的自定义属性。但似乎这些都不是必要的。
可编辑和不可编辑之间的区别似乎在于:
- 您可以在"
style.xml
"声明中使用可编辑属性。
- 自定义类的构造函数需要以不同的方式读取已编辑和未编辑的属性:通过
obtainStyledAttributes()
读取已编辑的属性,通过attr.getAttributeValue()
或类似方法读取未编辑的属性。
在大多数教程和示例中,我只看到了使用obtainStyledAttributes()
的情况。然而,这在没有使用样式直接声明属性的情况下是行不通的。如果您按照大多数教程所示使用obtainStyledAttributes()
,则根本无法获取属性attrib1
;您只会得到attrib2
,因为它是在样式中声明的。直接使用attr.getAttributeValue()
方法可以解决这个问题:
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
String attrib1 = attrs.getAttributeValue(null, "attrib1");
}
由于我们没有使用命名空间来声明 "attrib1
",因此在 getAttributeValue()
中将命名空间参数传递为 null
。