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

Ven*_*r85 166 android android-custom-view android-view android-custom-attributes

我正在写一些自定义视图,它们共享一些同名的属性.在他们各自的<declare-styleable>部分,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>
Run Code Online (Sandbox Code Playgroud)

我收到一个错误,说明myattr1并且myattr2已经定义了.我发现我应该省略formatfor myattr1myattr2in 的属性MyView2,但如果我这样做,我在控制台中获得以下错误:

[2010-12-13 23:53:11 - MyProject] ERROR: In <declare-styleable> MyView2, unable to find attribute 
Run Code Online (Sandbox Code Playgroud)

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

Ven*_*r85 364

解决方案:只需从两个视图中提取公共属性,然后将它们直接添加为<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>
Run Code Online (Sandbox Code Playgroud)

  • @Google:糟糕的设计 (43认同)
  • 当`myattr1`是`MyView1`中的字符串和`MyView2`中的整数时会发生什么? (10认同)
  • @ foxx1337只需使用`<attr name ="myattr1"format ="string | integer"/>`.适合我. (6认同)
  • 我不这么认为,例如我们可以有'orientation'属性,对于某些视图,它是'水平'/'垂直'和其他'landscape'/'portrait'/'square'.从我的观点来看,这是Android中的一个错误(或至少是不一致的行为)(请记住:1.stylable属性总是以prefix = view name开头,如果你为这些视图创建单独的库项目,一切都会正常工作) (4认同)
  • 当我按照这个答案时,我得到`错误:在<declare-styleable> com_app_view_widget中,无法找到属性customAttr`对于我尝试声明的所有视图.有任何想法吗? (4认同)
  • 我认为你不能,但即使你可以,我认为这些属性名称有点错误:) (2认同)
  • @Dapp清理并重建了项目,错误消息也消失了. (2认同)
  • @Mygod通过接受2种类型,当只允许1时,你正在失去xml字段类型验证. (2认同)
  • @GlennBech确切.为什么我们甚至需要声明一个CustomView的样式并将可能的属性放在其中,如果它仍然可以在不同的样式下与其他同名的attr冲突.谷歌似乎在整个Android开发过程中过于复杂. (2认同)

Pri*_*hal 47

我发布了这个答案,因为上面发布的解决方案在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>
Run Code Online (Sandbox Code Playgroud)

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

  • 这对我有用。我找不到从接受的答案中引用代码中提取的属性的方法。 (2认同)

Sur*_*gch 24

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

但是,还有其他一些事情需要注意(这就是我也在添加答案的原因):

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

这是我在最近的一个项目中所做的,它有两个自定义视图,它们共享相同的属性.只要自定义视图仍然具有属性的名称并且不包含a 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>
Run Code Online (Sandbox Code Playgroud)

简化的例子

实际上,我甚至不需要将属性放在自定义名称下.只要我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>
Run Code Online (Sandbox Code Playgroud)

对于一个大的项目,不过,这可能会导致混乱,并在一个位置上定义它们可能会更好(如建议在这里).


小智 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>
Run Code Online (Sandbox Code Playgroud)