【问题标题】:How to declare several stylable attributes with the same name for different tags?如何为不同的标签声明几个具有相同名称的样式属性?
【发布时间】:2013-09-16 12:19:35
【问题描述】:

我希望我的 ViewA 和 ViewB 都有“标题”标签。但我不能把这个放在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”已被定义Another question 显示了这个解决方案:

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

我该如何解决这个问题?

【问题讨论】:

标签: java android xml declare-styleable styleable


【解决方案1】:

您发布的链接确实为您提供了正确答案。它建议您这样做:

<?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都可以访问了。

如果有机会,请阅读此答案:Link。相关引述:

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

【讨论】:

  • 这似乎不再适用(或者至少在使用 Android Studio 2.3 时)。当我在根目录中定义属性时,我收到一条错误消息,指出无法解析这些资源。我认为您需要定义具有任何共享属性的父级。
【解决方案2】:

改为这样做。不需要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 属性不会在另一个文件中自动继承,对吧?还是我错过了什么?您能否在回答中澄清这一点?
【解决方案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>
<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>

没关系!!

【讨论】:

    【解决方案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>
    

    在你的 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);
    

    【讨论】:

    • 这不起作用。它不会生成 ViewB_title。 ViewA_title 不能用于 ViewB 元素,因为它的 ID 会与 ViewB_min 冲突。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-30
    • 1970-01-01
    • 1970-01-01
    • 2020-05-27
    相关资源
    最近更新 更多