Benutzerdefinierte Attribute in styles.xml


178

Ich habe ein benutzerdefiniertes Widget erstellt und deklariere es in layout.xml. Ich habe auch einige benutzerdefinierte Attribute in attr.xml hinzugefügt. Wenn ich jedoch versuche, diese Attribute in einem Stil in styles.xml zu deklarieren, gibt es mirNo resource found that matches the given name: attr 'custom:attribute'.

Ich habe das xmlns:custom="http://schemas.android.com/apk/res/com.my.package"in alle Tags in styles.xml eingefügt, einschließlich <?xml>, <resources>und <style>, aber es gibt mir immer noch den gleichen Fehler, dass mein benutzerdefinierter XML-Namespace nicht gefunden werden kann.

Ich kann jedoch meinen Namespace verwenden, um der Ansicht in meiner layout.xml manuell Attribute zuzuweisen, sodass am Namespace nichts falsch ist. Mein Problem besteht darin, styles.xml auf meine attr.xml aufmerksam zu machen.


1
cutsom:xmlns=...?? sollte nicht sein xmlns:cutsom=...?
Selvin

Ja, das ist es, was ich dafür bekomme, dass ich Copy / Paste nicht benutze, danke
styler1972

Antworten:


362

Ich habe es herausgefunden! Die Antwort lautet , den Namespace NICHT im Stil anzugeben.

<?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
Der Fehler verschwindet, aber meine Ansicht übernimmt nicht den Attributwert, während die anderen (nicht benutzerdefinierten) Attribute übernommen werden. Mein besonderes Attribut ist eine Aufzählung. Funktioniert das obige Snippet für Sie?
Paul Lammertsma

@PaulLammertsma Ich verwende eine Aufzählung und das scheint auch bei mir nicht zu funktionieren. Wenn Sie nicht über das benutzerdefinierte Namespace-Attribut xmlns verfügen, können Sie einen beliebigen Wert für das Elementnamenattribut eingeben und es wird kompiliert.
David Snabel-Caunt

@ DavidCaunt Ich habe irgendwann bekommen, woran ich gearbeitet habe . Ich habe schließlich eine Zeichenfolge für die declare-stylableanstelle einer Aufzählung verwendet. Ich bin mir nicht sicher, warum Aufzählungen nicht funktionierten, aber diese Umgehung war gut genug für mich.
Paul Lammertsma

3
Dies wird nicht einmal für mich mit API Level 16 kompiliert.
David Miler

3
Während dies funktioniert, vermute ich, dass es ein Problem beim Auflösen der Attribute geben würde, wenn ein Attribut mit demselben Namen in zwei oder mehr Paketen, aber mit unterschiedlichen Paketnamen vorhanden wäre.
AndroidDev

43

Die obige Antwort funktioniert für mich. Ich habe eine kleine Änderung versucht. Ich erkläre sie für eine Klasse im Ressourcenelement als stilbar.

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

In declare-styleable hat das name- Attribut auf einen Klassennamen verwiesen, sodass ich einen View-Klassenaufruf "com.my.package.name.VerticalView" hatte. Es stellte dar, dass diese Deklaration in VerticalView oder Unterklassen von VerticalView verwendet werden muss. so können wir Stil wie folgt deklarieren:

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

Aus diesem Grund haben wir den Namespace im Ressourcenelement nicht deklariert, es funktioniert immer noch.


11

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>

Werte / Farben.xml

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

values ​​/ dimension.xml

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

Verwenden von

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

Geben Sie hier die Bildbeschreibung ein

DEMO


10

Die Modifikation von Styler und Vince hat bei mir funktioniert. Ich wollte darauf hinweisen, dass die Erklärung von @ vince möglicherweise nicht ganz richtig ist.

Um die Hypothese zu testen, dass das Namensattribut der declare-styleableÜbereinstimmung mit dem Namen der benutzerdefinierten Ansichtsklasse den Zugriff auf das benutzerdefinierte Attribut ohne einen Namespace ermöglicht, habe ich den Namen der geändert declare-styleable(die benutzerdefinierte Ansicht wurde benannt TestViewFont:

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

Ich habe dann den obtainStyledAttributesAufruf in der benutzerdefinierten Ansicht geändert , um dies widerzuspiegeln:

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

Der Code lief noch. Ich denke also nicht, dass es eine Art Selbstbeobachtung durch declare-styleabledie Klasse ist, nach der es benannt ist.

Daher glaube ich, dass alle benutzerdefinierten Attribute verwendet werden können, um einen Stil zu deklarieren, ohne auf einen Namespace zu verweisen.

Trotzdem, danke für all die Hilfe, es hat mein Problem gelöst.


Tatsächlich haben Attribute denselben Namespace, unabhängig davon, ob sie in einem declare-styleableBlock deklariert sind oder nicht. (Entschuldigung, ich kann die Referenzseite dafür nicht finden ...) Mit Ausnahme von Attributen aus dem androidNamespace sollten Sie nur den Attributnamen angeben.
Pr-Shadoko

3
  • Definieren Sie einige Attribute

<declare-styleable name="refreshPullRefreshLayout">
        <attr name="refreshColors" format="reference"/>
        <attr name="refreshColor" format="reference"/>
</declare-styleable>
  • Verwenden Sie es in Layout-Dateien wie

<com.aolphn.PullRefreshLayout
     app:refreshColor="@color/main_green"
     app:refreshColors="@array/refresh_color"/>
  • Verwenden Sie es schließlich in der Style-Datei

    Der Unterschied zwischen Style-Datei und Layout-Datei besteht darin, dass keine Präfixe hinzugefügt werden app:
<style name="refreshStyle">
    <item name="refreshColor">@color/main_green</item>
    <item name="refreshColors">@array/refresh_color</item>
</style>

Probieren Sie es aus, haben Sie einen schönen Tag, das funktioniert für mich.


2

Falls es jemand anderem hilft, war mein Fehler, dass meine benutzerdefinierte Ansichtsklasse AttributeSet.getAttributeValue aufrief, z

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

... was dazu führte, dass mein benutzerdefiniertes Attribut für meine benutzerdefinierte Ansicht nicht eingelesen wurde.

Das Update sollte obtainStyledAttributesin meiner benutzerdefinierten Ansicht verwendet werden:

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

Ein Hinweis darauf, dass dies korrekt funktioniert, ist, dass Sie bei R.styleable.MyTextViewStyleable_customFontgedrückter Strg- / Apple- Taste auf klicken können , um direkt zu Ihrer attrs.xml-Definition zu gelangen.

Ich habe eine Weile gebraucht, um diesen kritischen Unterschied zwischen meinem Code und den anderen Beispielen zu erkennen, da das benutzerdefinierte Attribut gut funktioniert hat, wenn es direkt über das Layout-XML (anstelle eines Stils) übergeben wurde.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.