Пользовательские атрибуты в styles.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, поэтому нет ничего неправильного в пространстве имен. Моя проблема заключается в том, что make.style.xml знает мой attr.xml.

Ответ 1

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

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

Ответ 2

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

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

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

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

Ответ 3

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

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

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

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

Ответ 4

Значения /styles.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>

Значения /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"
    />

enter image description here

DEMO

Ответ 5

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

Ответ 6

  • Определите некоторые атрибуты

<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: prefiex app:
<style name="refreshStyle">
    <item name="refreshColor">@color/main_green</item>
    <item name="refreshColors">@array/refresh_color</item>
</style>

Попробуй, хорошего дня, у меня это работает.