【问题标题】:Format attribute value "android:drawable" not valid格式属性值“android:drawable”无效
【发布时间】:2011-03-30 01:42:48
【问题描述】:

我正在尝试为我的按钮创建自定义属性,但我不知道在属性声明中我必须对图像使用哪种格式...

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

    <declare-styleable name="TCButton">
        <attr name="Text" format="string"/>
        <attr name="BackgroundImage" format="android:drawable"  />
    </declare-styleable>


</resources>

错误在于格式="android:drawable"...

【问题讨论】:

    标签: android


    【解决方案1】:

    您可以使用 format="integer"、drawable 的 resource idAttributeSet.getDrawable(...)

    这是一个例子。

    在 res/values/attrs.xml 中将属性声明为整数:

    <resources>
        <declare-styleable name="MyLayout">
            <attr name="icon" format="integer" />
        </declare-styleable>
    </resources>
    

    将属性设置为布局中的可绘制 id:

    <se.jog.MyLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        myapp:icon="@drawable/myImage"
    />
    

    从自定义小部件组件类中的属性中获取可绘制对象:

    ImageView myIcon;
    //...
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyLayout);
    Drawable drawable = a.getDrawable(R.styleable.MyLayout_icon);
    if (drawable != null)
        myIcon.setBackgroundDrawable(drawable);
    

    要查看所有可能的选项,请查看android src here

    【讨论】:

    • 再看一遍,可以补充一点,错误的命名空间声明不会产生编译时错误。在此示例中,如果在 se.jog.mob 中声明了 class MyLayout,则它可能看起来像 xmlns:myapp="http://schemas.android.com/apk/res/se.jog.mob"
    • 使用完样式属性后,您应该调用a.recycle()
    • 在 gradle 项目中,自定义架构应始终为“schemas.android.com/apk/res-auto
    • 是的,这里有一个关于弃用的问题:stackoverflow.com/questions/11947603/…
    • 使用整数不允许我从 XML 中的 @drawable 中进行选择。我让你使用 fromat="reference" 然后它起作用了。
    【解决方案2】:

    我觉得用它作为简单的参考会更好:

    <declare-styleable name="TCButton">
            <attr name="customText" format="string"/>
            <attr name="backgroundImage" format="reference"  />
    </declare-styleable>
    

    并像这样在你的xml中设置它:

    <your.package.name.TCButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        custom:customText="Some custom text"
        custom:backgroundImage="@drawable/myImage"
    />
    

    在你的类中设置如下属性:

    public TCButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MembershipItemView, 0, 0);
    
        String customText;
        Drawable backgroundImage;
        try {
            customText = a.getString(R.styleable.TCButton_customText);
            backgroundImage = a.getDrawable(R.styleable.TCButton_backgroundImage);
        } finally {
            a.recycle();
        }
    
        if(!TextUtils.isEmpty(customText)) {
          ((TextView)findViewById(R.id.yourTextView)).setText(customText);
        }
    
        if(null != backgroundImage) {                    
            ((ImageView)findViewById(R.id.yourImageView)).setBackgroundDrawable(backgroundImage);
        }
    }
    

    PS: 不要忘记为您正在使用自定义视图的布局的根元素添加这一行

    xmlns:custom="http://schemas.android.com/apk/res-auto"
    

    如果您不设置此项,您将无法访问您的自定义属性。

    【讨论】:

    • 您的示例中的自定义 backgroundImage 属性设置是错误的。更像:custom:backgroundImage="@drawable/myImage"
    • 这是最好的答案。当您使用 format="reference" 时,您将在 custom:backgroundImage="@drawable/myImage" 看到选择资源的下拉列表
    【解决方案3】:

    从 AOSP 代码中,我发现了 google 工程师如何声明 ImageView#src attr。

    <declare-styleable name="ImageView">
        <attr name="src" format="reference|color" />
        <attr name="scaleType">
            <enum name="matrix" value="0" />
            <enum name="fitXY" value="1" />
            <enum name="fitStart" value="2" />
            <enum name="fitCenter" value="3" />
            <enum name="fitEnd" value="4" />
            <enum name="center" value="5" />
            <enum name="centerCrop" value="6" />
            <enum name="centerInside" value="7" />
        </attr>
        <attr name="adjustViewBounds" format="boolean" />
        <attr name="maxWidth" format="dimension" />
        <attr name="maxHeight" format="dimension" />
        <attr name="tint" format="color" />
        <attr name="baselineAlignBottom" format="boolean" />
        <attr name="cropToPadding" format="boolean" />
        <attr name="baseline" format="dimension" />
        <attr name="drawableAlpha" format="integer" />
        <attr name="tintMode" />
    </declare-styleable>
    

    以上代码是一个示例,它可以涵盖我们开发中的大多数情况。

    【讨论】:

    • 发现以上内容有帮助(),点赞。
    猜你喜欢
    • 1970-01-01
    • 2020-02-04
    • 1970-01-01
    • 1970-01-01
    • 2014-11-22
    • 2016-04-10
    • 2012-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多