31

I want both my ViewA and ViewB to have the "title" tag. But I can't put this in 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>

because of the error Attribute "title" has already been defined. Another question shows this solution:

<?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>

but in that case, R.styleable.ViewA_title and R.styleable.ViewB_title are not generated. I need them for reading the attributes from the AttributeSet using the following code:

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

How can I solve this?

4

4 回答 4

49

您发布的链接确实为您提供了正确的答案。这就是它建议您执行的操作:

<?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_title两者R.styleable.ViewB_title都可以访问。

如果有机会,请通读此答案:Link。相关报价:

您可以在顶部元素或元素内部定义属性。如果我要在多个地方使用 attr,我将它放在根元素中。

于 2013-09-19T06:51:58.903 回答
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>

这个不行。</p>

<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>

这也行不通。</p>

<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>

这没关系!

于 2017-11-13T10:41:02.943 回答
4

改为这样做。不需要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>

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

于 2017-04-26T13:01:21.430 回答
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);
于 2013-09-16T12:27:36.733 回答