2013-09-16 24 views
17

我希望我的ViewA和ViewB都有“标题”标签。但我不能把这个attrs.xml如何为不同的标签声明几个具有相同名称的stylable属性?

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

因为错误属性“称号”已被定义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); 

我该如何解决这个问题?

+0

类似于http://stackoverflow.com/questions/4434327/same-named-attributes-in-attrs-xml-for-custom-view – Suragch

回答

32

你已经张贴不给你正确的答案的链接。这是它表明你做的事:

<?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,而不是将它放在根元素中。

+0

这似乎不再成立(或至少在使用Android Studio 2.3时)。当我在根中定义属性时,出现错误,指出这些资源无法解析。我认为你需要定义一个具有共享属性的父项。 – BioeJD

+0

现在不适用于Android Studio。 – user3269713

+0

截至2018-2的正确答案是https://stackoverflow.com/a/43635002/1963973 – marianosimone

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); 
+0

这是行不通的。它不会生成ViewB_title。 ViewA_title不能用于ViewB元素,因为其ID将与ViewB_min冲突。 – Andreas

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> 

这是因为一旦titleViewA声明,它不需要(也不能)被再次在另一个declare-styleable

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

这是OK!

相关问题