Пользовательские атрибуты в стилях.XML


Я создал пользовательский виджет, и я объявляю его в макет.XML. Я также добавил некоторые пользовательские атрибуты в attr.XML. Однако при попытке объявить эти атрибуты в стиле в стилях.xml, это дает мне No resource found that matches the given name: attr 'custom:attribute'.

я поставил xmlns:custom="http://schemas.android.com/apk/res/com.my.package" во всех тегах в стилях.xml, включая <?xml>,<resources> и <style>, но он по-прежнему дает мне ту же ошибку, что он не может найти свое собственное пространство имен XML.

Я могу, однако, использовать мое пространство имен вручную назначьте атрибуты для представления в моем макете.xml, так что нет ничего плохого в пространстве имен. Моя проблема заключается в создании стилей.xml знает о моем attr.XML.

5 154

5 ответов:

Я все понял! Ответ заключается в не указать пространство имен в стиле.

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

выше ответ работает для меня, я попробовал небольшое изменение, я объявляю styleable для класса в элементе resources.

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

на declare-styleable на имя атрибут ссылается на имя класса, поэтому у меня был вызов класса представления "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>

вот почему мы не объявили пространство имен в элемент ресурсов, он все еще работает.

модификация стайлера и Винса работала на меня. Я хотел бы отметить, что объяснение @vince может быть не совсем точным.

чтобы проверить гипотезу, что имя атрибута declare-styleable соответствие имени пользовательского класса представления позволяет нам получить доступ к пользовательскому атрибуту без пространства имен я изменил имя 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 класса, в честь которого он назван.

таким образом, я убежден, что любые пользовательские атрибуты могут быть использованы для объявления стиля без ссылки на пространство имен.

несмотря на это, спасибо за помощь, ребята, это решило мою проблему.

в случае, если это поможет кому-то еще, моя ошибка заключалась в том, что мой пользовательский класс представления вызывал 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-файл макета (а не через стиль).

ценностей/стили.xml

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

значения / attrs.xml

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

ценностей/цвета.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

демо