如何为不同的标签声明具有相同名称的多个可样式化属性?

35

我希望我的 ViewA 和 ViewB 都有 "title" 标签,但我不能把它放在 attrs.xml 中:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="ViewA">
        <attr name="title" format="string" />
    </declare-styleable>
    <declare-styleable name="ViewB">
        <attr name="title" format="string" />
        <attr name="max" format="integer" />
    </declare-styleable>
</resources>

由于错误属性"title"已经被定义另一个问题提供了以下解决方案:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="title" format="string" />
    <declare-styleable name="ViewB">
        <attr name="max" format="integer" />
    </declare-styleable>
</resources>

但在这种情况下,R.styleable.ViewA_titleR.styleable.ViewB_title都没有被生成。我需要它们来使用以下代码从AttributeSet中读取属性:

TypedArray a=getContext().obtainStyledAttributes( as, R.styleable.ViewA);
String title = a.getString(R.styleable.ViewA_title);

我该如何解决这个问题?


类似于https://dev59.com/i2855IYBdhLWcg3wSSKl - Suragch
4个回答

52
您发布的链接确实提供给您正确的答案。此链接建议您执行以下操作:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="title" format="string" />
    <declare-styleable name="ViewA">
        <attr name="title" />
    </declare-styleable>
    <declare-styleable name="ViewB">
        <attr name="title" />
        <attr name="max" format="integer" />
    </declare-styleable>
</resources>

现在,R.styleable.ViewA_titleR.styleable.ViewB_title都可以访问。

如果有机会,请阅读这个答案:链接。相关引用:

你可以在顶级元素或<resources>元素中定义属性。如果我要在多个地方使用一个属性,我会将其放在根元素中。


1
更新2022:这个完全没问题!(已在最新的Android Studio和Gradle上测试过) - Top-Master

5
这样做更好。不需要parent标签。
<resources>
    <declare-styleable name="ViewA">
        <attr name="title" format="string" />
    </declare-styleable>

    <declare-styleable name="ViewB" >
        <attr name="title" /> 
        <attr name="min" format="integer" />
        <attr name="max" format="integer" />
    </declare-styleable>
</resources>

这是因为一旦在 ViewA 中声明了 title,就不需要(也不能)在另一个 declare-styleable 中再次声明它。

如果我理解正确的话,resources 标签形成了继承的框架,对吗?所以 title 属性在另一个文件中不会自动继承,对吗?或者我有什么地方理解错误吗?您能否在回答中澄清一下这个问题? - Benjamin Basmaci
1
@BenjaminBasmaci 没有这样的框架,请定义一次并在整个模块中使用(不重复类型)。 - Top-Master

4
<resources>
<declare-styleable name="ViewA">
    <attr name="title" format="string" />
</declare-styleable>

<declare-styleable name="ViewB" parent="ViewA"> // inherit from ViewA
    <attr name="min" format="integer" />
    <attr name="max" format="integer" />
</declare-styleable>

这个不起作用。

<resources>
<attr name="title" format="string" />
<declare-styleable name="ViewA">
    <attr name="title" />
</declare-styleable>
<declare-styleable name="ViewB">
    <attr name="title" />
    <attr name="max" format="integer" />
</declare-styleable>

这也不起作用。
<resources>
<declare-styleable name="ViewA">
    <attr name="title" format="string" />
</declare-styleable>

<declare-styleable name="ViewB" >
    <attr name="title" /> 
    <attr name="min" format="integer" />
    <attr name="max" format="integer" />
</declare-styleable>

这还可以!


3
你需要使用继承。
<resources>
    <declare-styleable name="ViewA">
        <attr name="title" format="string" />
    </declare-styleable>

    <declare-styleable name="ViewB" parent="ViewA"> // inherit from ViewA
        <attr name="min" format="integer" />
        <attr name="max" format="integer" />
    </declare-styleable>
</resources>

在您的Java代码中:
String namespace = "http://schemas.android.com/apk/res/" + getContext().getPackageName();
int title_resource = attrs.getAttributeResourceValue(namespace, "title", 0); 
String title = "";
if(title_resource!=0){
  title = getContext().getString(title_resource);
}

int min = attrs.getAttributeResourceValue(namespace, "min", 0); // read int value
int max = attrs.getAttributeResourceValue(namespace, "max", 0);

2
这个不起作用。它没有生成ViewB_title。由于其ID会与ViewB_min冲突,因此无法将ViewA_title用于ViewB元素。 - Andreas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接