Niestandardowe atrybuty w styles.xml


178

Utworzyłem niestandardowy widget i ogłaszam go w layout.xml. Dodałem także niestandardowe atrybuty w pliku attr.xml. Jednak gdy próbuję zadeklarować te atrybuty w stylu w styles.xml, daje mi toNo resource found that matches the given name: attr 'custom:attribute'.

Umieściłem xmlns:custom="http://schemas.android.com/apk/res/com.my.package"we wszystkich tagach w styles.xml, w tym <?xml>, <resources>i <style>, ale nadal daje mi ten sam błąd, że nie może znaleźć mojej niestandardowej przestrzeni nazw XML.

Mogę jednak użyć mojej przestrzeni nazw, aby ręcznie przypisać atrybuty do widoku w moim layout.xml, więc nie ma nic złego w przestrzeni nazw. Mój problem polega na uświadomieniu styles.xml mojego attr.xml.


1
cutsom:xmlns=...?? nie powinno być xmlns:cutsom=...?
Selvin

Tak, właśnie to dostaję za to, że nie korzystałem z funkcji kopiuj / wklej, dzięki
styler1972

Odpowiedzi:


362

Rozgryzłem to! Odpowiedź brzmi: NIE należy określać przestrzeni nazw w stylu.

<?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
Błąd znika, ale mój widok nie przyjmuje wartości atrybutu, podczas gdy przyjmuje inne (niestandardowe) atrybuty. Moim szczególnym atrybutem jest wyliczenie. Czy powyższy fragment działa dla Ciebie?
Paul Lammertsma,

@PaulLammertsma Używam wyliczenia i to też nie działa dla mnie. Jeśli nie masz niestandardowego atrybutu przestrzeni nazw xmlns, możesz wpisać dowolną wartość atrybutu nazwy elementu, która się skompiluje.
David Snabel-Caunt,

@DavidCaunt W końcu dostałem to, nad czym pracowałem . W końcu użyłem łańcucha declare-stylablezamiast enum. Nie jestem pewien, dlaczego wyliczenia nie działały, ale to obejście było dla mnie wystarczająco dobre.
Paul Lammertsma,

3
To nawet mnie nie kompiluje, używając API na poziomie 16
David Miler

3
Chociaż działa, podejrzewam, że wystąpiłby problem z rozwiązaniem atrybutów, gdyby atrybut o tej samej nazwie istniał w dwóch lub większej liczbie pakietów, ale o różnych nazwach pakietów.
AndroidDev,

43

powyższa odpowiedź jest dla mnie sprawdzona, próbowałem drobnej zmiany, deklaruję stylowy dla klasy element zasobów.

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

w declare-styleable The nazwa atrybutu odwołuje nazwę klasy, więc miałem widok klasy połączenia „com.my.package.name.VerticalView”, to stwierdzenie, że przedstawiciele muszą mieć zastosowanie w VerticalView lub podklas VerticalView. więc możemy zadeklarować styl w ten sposób:

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

dlatego nie zadeklarowaliśmy przestrzeni nazw w elemencie zasobów, nadal działa.


11

wartości / styles.xml

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

wartości / attrs.xml

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

wartości / kolory.xml

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

wartości / dimens.xml

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

Za pomocą

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

wprowadź opis zdjęcia tutaj

PRÓBNY


10

Modyfikacja Stylera i Vince'a działała dla mnie. Chciałem zauważyć, że wyjaśnienie @ vince'a może nie być całkowicie dokładne.

Aby przetestować hipotezę, że atrybut name declare-styleablepasujący do nazwy niestandardowej klasy widoku umożliwia nam dostęp do atrybutu niestandardowego bez przestrzeni nazw, zmieniłem nazwę declare-styleable(widok niestandardowy został nazwany TestViewFont:

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

Następnie zmieniłem obtainStyledAttributespołączenie w widoku niestandardowym, aby odzwierciedlić to:

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

Kod nadal działał. Więc nie sądzę, że jest to jakaś introspekcjadeclare-styleable klasy, od której pochodzi jej nazwa.

W ten sposób jestem przekonany, że wszelkie niestandardowe atrybuty mogą być użyte do deklarowania stylu bez odwoływania się do przestrzeni nazw.

Niezależnie od tego, dzięki za pomoc, chłopaki rozwiązali mój problem.


W rzeczywistości atrybuty mają tę samą przestrzeń nazw, niezależnie od tego, czy są zadeklarowane w declare-styleablebloku, czy nie. (przepraszam, nie mogę znaleźć strony referencyjnej dla tego…) Z wyjątkiem atrybutów z androidprzestrzeni nazw, powinieneś podać tylko nazwę atrybutu.
pr-shadoko

3
  • Zdefiniuj niektóre atrybuty

<declare-styleable name="refreshPullRefreshLayout">
        <attr name="refreshColors" format="reference"/>
        <attr name="refreshColor" format="reference"/>
</declare-styleable>
  • Użyj go w pliku układu, takim jak

<com.aolphn.PullRefreshLayout
     app:refreshColor="@color/main_green"
     app:refreshColors="@array/refresh_color"/>
  • Na koniec użyj go w pliku stylu

    Różnica między plikiem stylu a plikiem układu polega na tym, że nie dodajemy prefiksów app:
<style name="refreshStyle">
    <item name="refreshColor">@color/main_green</item>
    <item name="refreshColors">@array/refresh_color</item>
</style>

Spróbuj, miłego dnia, to działa dla mnie.


2

Jeśli pomógłby komukolwiek innemu, mój błąd polegał na tym, że moja niestandardowa klasa widoku wywoływała AttributeSet.getAttributeValue np.

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

... co spowodowało, że mój niestandardowy atrybut nie został odczytany dla mojego widoku niestandardowego.

Poprawka polegała na użyciu obtainStyledAttributesw moim widoku niestandardowym:

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

Wskazówka, że ​​to działa poprawnie, polega na tym, że możesz Ctrl / Apple + kliknąć na, R.styleable.MyTextViewStyleable_customFontaby przejść bezpośrednio do definicji attrs.xml.

Zajęło mi trochę czasu zauważenie tej krytycznej różnicy między moim kodem a innymi przykładami, ponieważ niestandardowy atrybut działał dobrze, gdy był przekazywany bezpośrednio przez układ XML (zamiast przez styl).

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.