Спеціальні атрибути в 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, тому в просторі імен немає нічого поганого. Моя проблема полягає в тому, щоб зробити стилі.xml відомо про мій attr.xml.


1
cutsom:xmlns=...?? не повинно бути xmlns:cutsom=...?
Селвін

Так, це я отримую за те, що не використовую копіювати / вставляти спасибі, хоча
styler1972

Відповіді:


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
Помилка зникає, але мій погляд не приймає значення атрибута, тоді як він приймає інші (нестандартні) атрибути. Мій особливий атрибут - перерахунок. Чи працює вищезгаданий фрагмент для вас?
Пол Ламмерцма

@PaulLammertsma Я використовую перерахунок, і це, здається, не працює і для мене. Якщо у вас немає атрибута xmlns користувальницького простору імен, ви можете фактично ввести будь-яке значення для атрибута імені елемента, і воно буде компілюватися.
Девід Снабель-Конт

@DavidCaunt Зрештою я отримав те, над чим працював . Зрештою, я використовував рядок declare-stylableзамість enum. Я не впевнений, чому юнаки не працювали, але ця робота була для мене досить хорошою.
Пол Ламмерцма

3
Це навіть не компілюється для мене, використовуючи API lvl 16.
Девід Мілер

3
Хоча це працює, я підозрюю, що виникне проблема з вирішенням атрибутів, якщо атрибут з тим самим іменем існував у двох чи більше пакетах, але з різними назвами пакетів.
AndroidDev

43

вище відповідь працює для мене, я спробував змінити litte, я оголошую стильовим для класу в ресурсі елемент.

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

в сповіщайте-styleable , то ім'я атрибута посилається ім'я класу, так що я мав вигляд класу виклик «com.my.package.name.VerticalView», він представляв це DECLARE має бути використання в 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>

тому ми не оголосили простір імен в ресурсі, він все ще працює.


11

значення / 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>

значення / color.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"
    />

введіть тут опис зображення

DEMO


10

Модифікація Styler та Vince працювала на мене. Я хотів би зазначити, що пояснення @ 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класу, яким він названий.

Таким чином, мене припускають, що будь-які спеціальні атрибути можуть бути використані для оголошення стилю, не посилаючись на простір імен.

Незалежно, дякую за всю допомогу, хлопці, це вирішило мою проблему.


Насправді атрибути мають однаковий простір імен, незалежно від того, оголошені вони у declare-styleableблоці чи ні. (Вибачте, я не можу знайти довідкову сторінку для цього…) За винятком атрибутів із androidпростору імен, слід вказати лише ім’я атрибута.
pr-shadoko

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"/>
  • Нарешті, використовуйте його у файлі стилів

    Різниця між файлом стилю та файлом макета полягає в тому, що ми не додаємо префікс 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 (замість стилю).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.