自定义视图的attrs.xml中具有相同名称的属性

时间:2010-12-13 22:58:41

标签: android android-view android-custom-view android-custom-attributes

我正在编写一些自定义视图,这些视图共享一些同名的属性。在<declare-styleable>的{​​{1}}部分,我想对属性使用相同的名称:

attrs.xml

我收到一条错误消息,指出<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MyView1"> <attr name="myattr1" format="string" /> <attr name="myattr2" format="dimension" /> ... </declare-styleable> <declare-styleable name="MyView2"> <attr name="myattr1" format="string" /> <attr name="myattr2" format="dimension" /> ... </declare-styleable> </resources> myattr1已经定义。我发现我应该在myattr2中省略formatmyattr1的{​​{1}}属性,但如果我这样做,我会在控制台中收到以下错误:

myattr2

有没有办法可以实现这一点,也许某种命名空间(只是猜测)?

5 个答案:

答案 0 :(得分:337)

解决方案:只需从两个视图中提取常用属性,然后将它们直接添加为<resources>节点的子级:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="myattr1" format="string" />
    <attr name="myattr2" format="dimension" />

    <declare-styleable name="MyView1">
        <attr name="myattr1" />
        <attr name="myattr2" />
        ...
    </declare-styleable>

    <declare-styleable name="MyView2">
        <attr name="myattr1" />
        <attr name="myattr2" />
        ...
    </declare-styleable>
</resources>

答案 1 :(得分:39)

我发布此答案,因为上面发布的解决方案在Android Studio中无法解决。我需要在我的自定义视图中共享我的自定义属性,所以我在Android Studio中尝试了上述解决方案,但没有运气。所以我试验并试着去做。希望它可以帮助某人寻找同样的问题。

  <?xml version="1.0" encoding="utf-8"?>
    <resources>
    <!-- parent styleable -->
     <declare-styleable name="MyView">
         <attr name="myattr1" format="string" />
         <attr name="myattr2" format="dimension" />
     </declare-styleable>

     <!-- inheriting parent styleable -->
     <!-- also note "myBackgroundColor" belongs to child styleable"MyView1"-->
    <declare-styleable name="MyView1" parent="MyView">
        <attr name="myattr1" />
        <attr name="myattr2" />
        <attr name="myBackgroundColor" format="color"/>
    </declare-styleable>


    <!-- inheriting parent styleable -->
    <!-- same way here "myfonnt" belongs to child styelable "MyView2" -->
    <declare-styleable name="MyView2" parent="MyView">
        <attr name="myattr1" />
        <attr name="myattr2" />
        <attr name="myfont" format="string"/>
        ...
    </declare-styleable>
</resources>

这完全适合我。 我们需要创建一个父样式,然后我们需要继承父样式。例如,正如我上面所做的那样: 父样式名称MyView并将其继承到我的其他样式,如MyView1和MyView2。

答案 2 :(得分:20)

正如Priya Singhal回答的那样,Android Studio要求在自己的样式名称中定义公共属性名称。他们不能再扎根了。

但是,还有其他一些事情要注意(这就是为什么我也在添加答案):

  • 常见样式不需要与视图命名相同。 (感谢this answer指出这一点。)
  • 您不需要与父级一起使用继承。

实施例

这是我在最近的一个项目中所做的,它有两个共享相同属性的自定义视图。只要自定义视图仍具有属性的名称且不包含format,我仍然可以通过代码正常访问它们。

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- common attributes to all custom text based views -->

    <declare-styleable name="TextAttributes">
        <attr name="text" format="string"/>
        <attr name="textSize" format="dimension"/>
        <attr name="textColor" format="color"/>
        <attr name="gravity">
            <flag name="top" value="48" />
            <flag name="center" value="17" />
            <flag name="bottom" value="80" />
        </attr>
    </declare-styleable>

    <!-- custom text views -->

    <declare-styleable name="View1">
        <attr name="text"/>
        <attr name="textSize"/>
        <attr name="textColor"/>
        <attr name="gravity"/>
    </declare-styleable>

    <declare-styleable name="View2">
        <attr name="text"/>
        <attr name="textSize"/>
        <attr name="textColor"/>
        <attr name="gravity"/>
    </declare-styleable>

</resources>

简化示例

实际上,我甚至不需要将属性放在自定义名称下。只要我为至少一个自定义视图定义它们(给它们format),我就可以在任何地方使用它们(没有format)。所以这也有效(并且看起来更干净):

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="View1">
        <attr name="text" format="string"/>
        <attr name="textSize" format="dimension"/>
        <attr name="textColor" format="color"/>
        <attr name="gravity">
            <flag name="top" value="48" />
            <flag name="center" value="17" />
            <flag name="bottom" value="80" />
        </attr>
    </declare-styleable>

    <declare-styleable name="View2">
        <attr name="text"/>
        <attr name="textSize"/>
        <attr name="textColor"/>
        <attr name="gravity"/>
    </declare-styleable>

</resources>

对于一个大型项目,这可能会变得混乱,在一个位置顶部定义它们可能会更好(按照建议here)。

答案 3 :(得分:7)

谢谢刘易斯 我有同样的问题,你的继承解决方案给了我如下所示的提示,它工作正常。我只是在上面声明了公共属性,并再次在样式声明的主体中重写它而没有格式化。 我希望它有助于某人

<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- common attributes -->
     <attr name="myattr1" format="string" />
     <attr name="myattr2" format="dimension" />

 <!-- also note "myBackgroundColor" belongs to child styleable"MyView1"-->
<declare-styleable name="MyView1" >
    <attr name="myattr1" />
    <attr name="myattr2" />
    <attr name="myBackgroundColor" format="color"/>
</declare-styleable>

<!-- same way here "myfonnt" belongs to child styelable "MyView2" -->
<declare-styleable name="MyView2" parent="MyView">
    <attr name="myattr1" />
    <attr name="myattr2" />
    <attr name="myfont" format="string"/>
    ...
</declare-styleable>

答案 4 :(得分:1)

以防万一有人在尝试了可用解决方案后仍然遇到此问题。我坚持使用<form action="/Contact/QuickContact" data-ajax="true" data-ajax-begin="contact.onBegin" data-ajax-complete="contact.onComplete" data-ajax-failure="contact.onFailure" data-ajax-mode="replace" data-ajax-success="contact.onSuccess" data-ajax-update="#quickContactForm" id="form0" method="post" novalidate="novalidate"><input name="__RequestVerificationToken" type="hidden" value="EQj3G0b56_1saLORAmRCPqoGM-CgCYizgCn-ete0v-Ky_Ok7ioycTe7YlfVzZVAm-AtEIJpRh1n1gKb4sMfU-5lTKDdAZeMNyd85IFpRoRo1"> <div class="form-group"> <input class="form-control text-box single-line input-validation-error" data-val="true" data-val-length="Your name must be at least 6 characters long." data-val-length-max="100" data-val-length-min="6" data-val-regex="Do you really have numbers or symbols in your name?" data-val-regex-pattern="^[a-zA-Z]*$" data-val-required="The Name field is required." id="Name" name="Name" placeholder="Enter your name..." type="text" value=""> <span class="text-danger tooltip field-validation-error" data-valmsg-for="Name" data-valmsg-replace="true" data-original-title="" title=""><span for="Name" class="">The Name field is required.</span></span> <input class="form-control text-box single-line input-validation-error" data-val="true" data-val-required="The Telephone field is required." id="Telephone" name="Telephone" placeholder="Enter your telephone..." type="tel" value=""> <span class="text-danger field-validation-error" data-valmsg-for="Telephone" data-valmsg-replace="true"><span for="Telephone" class="">The Telephone field is required.</span></span> <input type="submit" class="btn btn-block btn-primary" value="Submit"> </div> </form> 格式添加subtitle属性。

我的解决方案是删除格式。

之前:

string

后:

<attr name="subtitle" format="string"/>