styles.xml中的自定义属性


178

我已经创建了一个自定义窗口小部件,并在layout.xml中声明了它。我还在attr.xml中添加了一些自定义属性。但是,当尝试在styles.xml中以样式声明这些属性时,这给了我No resource found that matches the given name: attr 'custom:attribute'.

我已经将xmlns:custom="http://schemas.android.com/apk/res/com.my.package"styles.xml中的所有标记(包括<?xml><resources>和)放入了所有标记中<style>,但是仍然出现相同的错误,即找不到我的自定义XML名称空间。

但是,我可以使用命名空间在layout.xml中为视图手动分配属性,因此命名空间没有任何问题。我的问题在于使styles.xml了解我的attr.xml。


1
cutsom:xmlns=...?? 不应该xmlns:cutsom=...吗?
塞尔文,

是的,这就是我不使用复制/粘贴而得到的东西
styler1972

Answers:


362

我想到了!答案是不要在样式中指定名称空间。

<?xml version="1.0" encoding="utf-8" ?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <style name="CustomStyle">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>

        <item name="custom_attr">value</item> <!-- tee hee -->
    </style>
</resources>

13
错误消失了,但是我的视图没有采用属性值,而是采用了其他(非自定义)属性。我的特殊属性是一个枚举。上面的代码段对您有用吗?
Paul Lammertsma

@PaulLammertsma我正在使用一个枚举,这似乎也不适合我。如果您没有自定义名称空间xmlns属性,则实际上可以为项目名称属性键入所需的任何值,它将进行编译。
David Snabel-Caunt 2011年

@DavidCaunt我最终确实得到了我正在工作的东西。我最终使用字符串declare-stylable代替枚举。我不确定为什么枚举不起作用,但是这种变通方法对我来说已经足够了。
Paul Lammertsma,2011年

3
这甚至不编译对我来说,使用API拉特16
大卫·米勒

3
在这种情况下,我怀疑如果两个或多个程序包中存在相同名称但程序包名称不同的属性,则解析属性时会出现问题。
AndroidDev

43

上面的答案对我有用,我尝试了一次小小的改变,我在资源元素中声明了一个类的样式。

<declare-styleable name="VerticalView">
    <attr name="textSize" format="dimension" />
    <attr name="textColor" format="color" />
    <attr name="textBold" format="boolean" />
</declare-styleable>

define-styleable中name属性引用了一个类名,因此我有一个视图类调用“ com.my.package.name.VerticalView”,它表示此声明必须在VerticalView或VerticalView的子类中使用。所以我们可以这样声明样式:

<resources>
    <style name="verticalViewStyle">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">36dip</item>

        <item name="textSize">28sp</item>  <!-- not namespace prefix -->
        <item name="textColor">#ff666666</item>
        <item name="textBold">true</item>
    </style>
</resources>

这就是为什么我们没有在resources元素中声明名称空间的原因,它仍然有效。


11

values / styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    ...
    <item name="defaultButtonColor">@color/red</item>
    <item name="defaultButtonHeight">@dimen/dp_100</item>
</style>

values / attrs.xml

<resources>
    <attr name="defaultButtonColor" format="reference" />
    <attr name="defaultButtonHeight" format="reference"/>
</resources>

values / colors.xml

<resources>
    <color name="red">#f00</color>
</resources>

值/dimens.xml

<resources>
    <dimen name="dp_100">100dp</dimen>
</resources>

使用

<Button
    android:layout_width="wrap_content"
    android:layout_height="?attr/defaultButtonHeight"
    android:text="Button"
    android:textColor="?attr/defaultButtonColor"
    />

在此处输入图片说明

演示


10

Styler和vince的修改对我有用。我想指出,@ vince的解释可能并不完全准确。

为了检验这样的假设,即与declare-styleable自定义视图类的名称匹配的name属性允许我们在没有命名空间的情况下访问自定义属性,我更改了名称declare-styleable(自定义视图名为TestViewFont

<declare-styleable name="TextViewFont2">
    <attr name="font" format="integer"/>
</declare-styleable>

然后,我obtainStyledAttributes在自定义视图中更改了调用以反映此情况:

TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.TextViewFont2, 0, 0);

代码仍然运行。因此,我认为这不是declare-styleable它所命名的类的某种内省。

因此,我被认为可以使用任何自定义属性来声明样式,而无需引用名称空间。

无论如何,感谢所有帮助人员,它解决了我的问题。


实际上,无论是否在declare-styleable块中声明属性,属性都共享相同的名称空间。(对不起,我无法为此找到参考页面…。)除了android名称空间中的属性外,您仅应指定属性名称。
pr-shadoko '16

3
  • 定义一些属性

<declare-styleable name="refreshPullRefreshLayout">
        <attr name="refreshColors" format="reference"/>
        <attr name="refreshColor" format="reference"/>
</declare-styleable>
  • 在布局文件中使用它,例如

<com.aolphn.PullRefreshLayout
     app:refreshColor="@color/main_green"
     app:refreshColors="@array/refresh_color"/>
  • 最后在样式文件中使用它

    样式文件和布局文件之间的区别是我们不添加prefiex app:
<style name="refreshStyle">
    <item name="refreshColor">@color/main_green</item>
    <item name="refreshColors">@array/refresh_color</item>
</style>

试试吧,今天过得愉快,这对我有用。


2

万一它对其他人有帮助,我的错误是我的自定义视图类正在调用AttributeSet.getAttributeValue例如

String fontName = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "customFont");

...这导致我的自定义视图无法读取我的自定义属性。

解决方法是obtainStyledAttributes在我的自定义视图中使用:

 TypedArray styleAttrs = context.obtainStyledAttributes(attrs, R.styleable.MyTextViewStyleable);
 String fontName = styleAttrs.getString(R.styleable.MyTextViewStyleable_customFont);

这可以正常工作的提示是,您可以按住Ctrl / Apple +单击 R.styleable.MyTextViewStyleable_customFont直接进入attrs.xml定义。

我花了一段时间才发现我的代码与其他示例之间的关键区别,因为当直接通过布局XML(而不是通过样式)传递custom属性时,custom属性可以很好地工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.