Xml 中的自定义属性

我已经创建了一个自定义小部件,并在 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。

73994 次浏览

答案是 没有在样式中指定名称空间。

<?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>

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

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

声明式样中,姓名属性引用了一个类名,所以我有一个叫做“ com.my.package.name”的视图类。它表示此声明必须在 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 元素中声明名称空间,它仍然可以工作。

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类的内省它是以类的名字命名的。

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

不管怎样,谢谢你们的帮助,解决了我的问题。

如果对其他人有帮助的话,我的错误是我的自定义视图类调用了 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 (而不是通过样式)直接传入时,自定义属性工作得很好。

Value/styles.xml

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

Value/attrs.xml

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

Value/Colors.xml

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

值/维度. 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"
/>

enter image description here

演示

  • 定义一些属性

<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"/>
  • 最后在样式文件中使用它

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

试试吧,祝你愉快,这对我很管用。