【问题标题】:What's the point of declare-styleable?声明样式有什么意义?
【发布时间】:2012-09-23 13:02:03
【问题描述】:

假设我正在制作一些带有样式属性的新视图。我因此声明它们(这是how the documentation says to do it

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

    <declare-styleable name="TriangleView">
        <attr name="direction">
            <enum name="NE" value="0" />
            <enum name="NW" value="1" />
            <enum name="SW" value="2" />
            <enum name="SE" value="3" />
        </attr>
    </declare-styleable>

    <declare-styleable name="BannerView">
        <attr name="direction">
            <enum name="NE" value="0" />
            <enum name="NW" value="1" />
            <enum name="SW" value="2" />
            <enum name="SE" value="3" />
        </attr>
        <attr name="thickness" format="dimension" />
    </declare-styleable>
</resources>

但是,这不起作用,因为所有属性显然都在同一个命名空间中,并且我收到错误 Error: Attribute "direction" has already been defined

所以显然我必须像这样将明显重复的属性移到&lt;declare-styleable&gt; 之外:

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


    <attr name="direction">
        <enum name="NE" value="0" />
        <enum name="NW" value="1" />
        <enum name="SW" value="2" />
        <enum name="SE" value="3" />
    </attr>

    <declare-styleable name="BannerView">
        <attr name="thickness" format="dimension" />
    </declare-styleable>
</resources>

但这提出了两个问题:

  1. 如果可行,&lt;declare-styleable&gt; 到底有什么意义?
  2. 如果我希望属性在不同视图中表现不同怎么办?比如BannerView的方向只能是up或者down

【问题讨论】:

    标签: android attr android-custom-view android-resources declare-styleable


    【解决方案1】:

    &lt;declare-styleable&gt; 到底有什么意义?

    &lt;declare-stylable&gt; 标签让您可以为自定义视图声明属性,然后您可以在 xml 中为这些视图设置这些属性。使用属性实际上有 3 个部分:

    1. &lt;declare-stylable&gt; 标签内声明&lt;attr&gt;
    2. 在您的 xml 布局中定义一个自定义命名空间,指向您的应用程序包名称(例如 app)。在您的布局中使用自定义属性(例如app:direction="NW")。
    3. 在您的自定义视图中,使用AttributeSet 参数覆盖构造函数,获取TypedArray 并从中读取自定义属性(如果有),然后在构造函数中告诉视图如何正确使用这些属性。

    如果我希望属性在不同视图中表现不同怎么办? 例如,如果 BannerView 的方向只能向上或向下。

    试试这样的:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <attr name="direction">
            <enum name="NE" value="0" />
            <enum name="NW" value="1" />
            <enum name="SW" value="2" />
            <enum name="SE" value="3" />
        </attr>
    
        <declare-styleable name="TriangleView">
            <attr name="direction" />
        </declare-styleable>
    
        <declare-styleable name="BannerView">
            <attr name="direction" />
            <attr name="thickness" format="dimension" />
        </declare-styleable>
    </resources>
    

    当您为TriangleViewBannerView 构建xml 布局时,您可以使用app:direction="NW" 示例。在TriangleViewBannerView 中带有AttributeSet 的构造函数中,属性将具有与原始格式相同的格式,但是您使用该值 的操作取决于关于您在每个视图中的构造函数实现(两者可以相同或不同)。

    如果您希望为不同的视图以不同的方式定义属性(即不同的“格式”或“枚举”),那么您必须创建具有不同视图的不同属性名字。

    【讨论】:

    • 太棒了,实际上对 app-compat 库中定义的 attr 也有帮助!所以基本上,如果一个 attr 已经定义,它应该在 declare-styleable 中使用,而不是试图覆盖格式。酷酷酷。
    • 但是在布局 gradle 中坚持你使用 'xmlns:XXX="schemas.android.com/apk/res-auto"' 来声明命名空间,所以即使你使用两个命名空间:'xmlns:XXX" 和 'xmlns:XXY"并具有 的属性,并将布局文件中的视图属性声明为 XXX:a=..." 和 XXY:a=" ...”您遇到了命名空间冲突并收到“重复资源”错误。为什么?
    猜你喜欢
    • 2016-12-09
    • 1970-01-01
    • 1970-01-01
    • 2014-01-15
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 2013-06-16
    • 1970-01-01
    相关资源
    最近更新 更多