Atribut khusus di styles.xml

178

Saya telah membuat widget khusus, dan saya mendeklarasikannya di layout.xml. Saya juga telah menambahkan beberapa atribut khusus di attr.xml. Namun, ketika mencoba mendeklarasikan atribut ini dalam style di styles.xml, itu memberi sayaNo resource found that matches the given name: attr 'custom:attribute'.

Saya telah memasukkan xmlns:custom="http://schemas.android.com/apk/res/com.my.package"semua tag di styles.xml, termasuk <?xml>,, <resources>dan <style>, tetapi masih memberi saya kesalahan yang sama, sehingga tidak dapat menemukan namespace XML khusus saya.

Namun, saya dapat menggunakan namespace saya untuk secara manual menetapkan atribut ke tampilan di layout.xml saya, jadi tidak ada yang salah dengan namespace. Masalah saya terletak pada membuat styles.xml mengetahui attr.xml saya.

styler1972
sumber
1
cutsom:xmlns=...?? seharusnya tidak xmlns:cutsom=...?
Selvin
Ya, itulah yang saya dapatkan karena tidak menggunakan copy / paste terima kasih
styler1972

Jawaban:

362

Saya menemukan jawabannya! Jawabannya adalah untuk TIDAK menentukan namespace dalam style.

<?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>
styler1972
sumber
13
Kesalahan menghilang, tetapi pandangan saya tidak mengadopsi nilai atribut, sementara itu mengadopsi atribut lainnya (non-kustom). Atribut khusus saya adalah enum. Apakah cuplikan di atas berfungsi untuk Anda?
Paul Lammertsma
@ PaulLammertsma Saya menggunakan enum dan ini sepertinya tidak bekerja untuk saya juga. Jika Anda tidak memiliki atribut namespace xmlns khusus, Anda sebenarnya dapat mengetik nilai apa pun yang Anda suka untuk atribut nama item dan itu akan dikompilasi.
David Snabel-Caunt
@ Davidvida akhirnya saya mendapatkan apa yang saya kerjakan berfungsi. Saya akhirnya menggunakan string untuk declare-stylablebukan enum. Saya tidak yakin mengapa enum tidak berfungsi, tetapi upaya ini cukup baik untuk saya.
Paul Lammertsma
3
Ini bahkan tidak dapat dikompilasi untuk saya, menggunakan API lvl 16.
David Miler
3
Sementara ini berfungsi, saya menduga bahwa akan ada masalah menyelesaikan atribut jika atribut dengan nama yang sama ada di dua atau lebih paket tetapi dengan nama paket yang berbeda.
AndroidDev
43

jawaban di atas bekerja untuk saya, saya mencoba perubahan kecil, saya menyatakan gaya untuk kelas dalam elemen sumber daya.

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

dalam menyatakan-gaya , atribut nama mereferensikan nama kelas, jadi saya memiliki panggilan kelas tampilan "com.my.package.name.VerticalView", itu menyatakan pernyataan ini harus digunakan dalam VerticalView atau subkelas VerticalView. jadi kita dapat mendeklarasikan gaya seperti ini:

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

itu sebabnya kami tidak mendeklarasikan namespace di elemen sumber daya, itu masih berfungsi.

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

nilai / attrs.xml

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

values ​​/ colors.xml

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

nilai / dimens.xml

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

Menggunakan

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

masukkan deskripsi gambar di sini

DEMO

Phan Van Linh
sumber
10

Modifikasi Styler dan vince bekerja untuk saya. Saya ingin menunjukkan bahwa penjelasan @ vince mungkin tidak sepenuhnya akurat.

Untuk menguji hipotesis bahwa atribut nama yang declare-styleablecocok dengan nama kelas tampilan kustom memungkinkan kami untuk mengakses atribut kustom tanpa namespace saya mengubah nama declare-styleable(tampilan kustom bernama TestViewFont:

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

Saya kemudian mengubah obtainStyledAttributespanggilan dalam tampilan kustom untuk mencerminkan ini:

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

Kode masih berjalan. Jadi saya tidak berpikir itu semacam introspeksi oleh declare-styleablekelas yang dinamai.

Jadi saya dituntun untuk percaya bahwa atribut kustom apa pun dapat digunakan untuk mendeklarasikan gaya tanpa merujuk ke namespace.

Bagaimanapun, terima kasih atas semua bantuannya, ini menyelesaikan masalah saya.

Abid H. Mujtaba
sumber
Sebenarnya, atribut berbagi namespace yang sama, apakah mereka dinyatakan dalam declare-styleableblok atau tidak. (maaf, saya tidak dapat menemukan halaman referensi untuk ini ...) Kecuali untuk atribut dari androidnamespace, Anda hanya boleh menunjukkan nama atribut.
pr-shadoko
3
  • Tentukan beberapa atribut

<declare-styleable name="refreshPullRefreshLayout">
        <attr name="refreshColors" format="reference"/>
        <attr name="refreshColor" format="reference"/>
</declare-styleable>
  • Gunakan dalam file layout seperti

<com.aolphn.PullRefreshLayout
     app:refreshColor="@color/main_green"
     app:refreshColors="@array/refresh_color"/>
  • Akhirnya gunakan dalam file gaya

    Perbedaan antara file gaya dan file tata letak adalah kita tidak menambahkan prefiex app:
<style name="refreshStyle">
    <item name="refreshColor">@color/main_green</item>
    <item name="refreshColors">@array/refresh_color</item>
</style>

Cobalah, semoga harimu menyenangkan, ini bekerja untukku.

aolphn
sumber
2

Jika itu membantu orang lain, kesalahan saya adalah kelas tampilan kustom saya memanggil AttributeSet.getAttributeValue misalnya

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

... yang mengakibatkan atribut khusus saya tidak dibaca untuk tampilan kustom saya.

Perbaikannya adalah untuk digunakan obtainStyledAttributesdalam tampilan kustom saya:

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

Petunjuk bahwa ini berfungsi dengan benar adalah Anda dapat Ctrl / Apple + klik pada R.styleable.MyTextViewStyleable_customFontuntuk langsung dibawa ke definisi attrs.xml Anda.

Butuh beberapa saat untuk menemukan perbedaan kritis antara kode saya dan contoh lainnya, karena atribut khusus berfungsi dengan baik ketika diteruskan langsung melalui tata letak XML (alih-alih melalui gaya).

Dan J
sumber