Custom attributes in styles.xml

AndroidAndroid LayoutAndroid XmlAndroid Styles

Android Problem Overview


I have created a custom widget, and I'm declaring it in layout.xml. I have also added some custom attributes in attr.xml. However, when trying to declare these attributes in a style in styles.xml, it's giving me No resource found that matches the given name: attr 'custom:attribute'.

I have put the xmlns:custom="http://schemas.android.com/apk/res/com.my.package" in all of the tags in styles.xml, including <?xml>, <resources>, and <style>, but it still gives me the same error, that it can't find my custom XML namespace.

I can, however, use my namespace to manually assign attributes to the view in my layout.xml, so there is nothing wrong with the namespace. My issue lies in making styles.xml aware of my attr.xml.

Android Solutions


Solution 1 - Android

I figured it out! The answer is to NOT specify the namespace in the style.

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

Solution 2 - Android

above answer is worked for me, I tried a litte change, I declare styleable for a class in resources element.

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

in declare-styleable, the name attribute referenced a class name, so I had a view class call "com.my.package.name.VerticalView", it represented this declare must be use in VerticalView or subclasses of VerticalView. so we can declare style like this :

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

that's why we didn't declare namespace at resources element, it still work.

Solution 3 - Android

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>

values/dimens.xml

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

Using

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

enter image description here

DEMO

Solution 4 - Android

Styler and vince's modification worked for me. I wanted to point out that @vince's explanation may not be entirely accurate.

To test the hypothesis that the name attribute of the declare-styleable matching the name of the custom view class is allowing us to access the custom attribute without a namespace I changed the name of the declare-styleable (the custom view was named TestViewFont:

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

I then changed the obtainStyledAttributes call in the custom view to reflect this:

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

The code still ran. So I don't think it is some kind of introspection by the declare-styleable of the class it is named after.

Thus I am led to believe that any custom attributes can be used to declare a style without referring to a namespace.

Regardless, thanks for all the help guys, it resolved my issue.

Solution 5 - Android

  • Define some attributes
<declare-styleable name="refreshPullRefreshLayout">
        <attr name="refreshColors" format="reference"/>
        <attr name="refreshColor" format="reference"/>
</declare-styleable>
  • Use it in layout file like
<com.aolphn.PullRefreshLayout
     app:refreshColor="@color/main_green"
     app:refreshColors="@array/refresh_color"/>
  • Finally use it in style file

The difference between style file and layout file is we do not add prefiex app:

<style name="refreshStyle">
    <item name="refreshColor">@color/main_green</item>
    <item name="refreshColors">@array/refresh_color</item>
</style>

Try it ,have a nice day,this works for me.

Solution 6 - Android

In case it helps anybody else, my mistake was that my custom view class was calling AttributeSet.getAttributeValue e.g.

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

...which was resulting in my custom attribute not being read in for my custom view.

The fix was to use obtainStyledAttributes in my custom view:

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

A hint that this is working correctly is that you can Ctrl/Apple + click on the R.styleable.MyTextViewStyleable_customFont to get taken straight to your attrs.xml definition.

It took me a while to spot this critical difference between my code and the other examples, as the custom attribute worked fine when passed in directly through the layout XML (instead of through a style).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiontylerView Question on Stackoverflow
Solution 1 - AndroidtylerView Answer on Stackoverflow
Solution 2 - AndroidVinceStylingView Answer on Stackoverflow
Solution 3 - AndroidLinhView Answer on Stackoverflow
Solution 4 - AndroidAbid H. MujtabaView Answer on Stackoverflow
Solution 5 - AndroidaolphnView Answer on Stackoverflow
Solution 6 - AndroidDan JView Answer on Stackoverflow