Pertanyaan Cara mendapatkan enum yang dibuat di attrs.xml dalam kode


Saya membuat Tampilan kustom (menemukannya sini) dengan atribut bergaya tipe enum deklarasikan. Dalam xml sekarang saya bisa memilih salah satu entri enum untuk atribut custom saya. Sekarang saya ingin membuat metode untuk mengatur nilai ini secara terprogram, tetapi saya tidak dapat mengakses enum.

attr.xml

<declare-styleable name="IconView">
    <attr name="icon" format="enum">
        <enum name="enum_name_one" value="0"/>
        ....
        <enum name="enum_name_n" value="666"/>
   </attr>
</declare-styleable>     

layout.xml

<com.xyz.views.IconView
    android:id="@+id/heart_icon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:icon="enum_name_x"/>

Yang saya butuhkan adalah sesuatu seperti: mCustomView.setIcon(R.id.enum_name_x); Tetapi saya tidak dapat menemukan enum atau saya bahkan tidak tahu bagaimana saya bisa mendapatkan enum atau nama enum.


75
2017-08-22 13:57


asal


Jawaban:


Sepertinya tidak ada cara otomatis untuk mendapatkan enum Java dari sebuah atribut enum - di Java Anda bisa mendapatkan nilai numerik yang Anda tentukan - string tersebut untuk digunakan dalam file XML (seperti yang Anda tunjukkan).

Anda dapat melakukan ini di konstruktor pandangan Anda:

TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.IconView,
                0, 0);

    // Gets you the 'value' number - 0 or 666 in your example
    if (a.hasValue(R.styleable.IconView_icon)) {
        int value = a.getInt(R.styleable.IconView_icon, 0));
    }

    a.recycle();
}

Jika Anda ingin nilainya menjadi enum, Anda perlu memetakan nilai ke enum Java sendiri, misalnya:

private enum Format {
    enum_name_one(0), enum_name_n(666);
    int id;

    Format(int id) {
        this.id = id;
    }

    static Format fromId(int id) {
        for (Format f : values()) {
            if (f.id == id) return f;
        }
        throw new IllegalArgumentException();
    }
}

Kemudian di blok kode pertama Anda bisa menggunakan:

Format format = Format.fromId(a.getInt(R.styleable.IconView_icon, 0))); 

(meskipun melempar pengecualian pada titik ini mungkin bukan ide bagus, mungkin lebih baik memilih nilai default yang masuk akal)


74
2017-09-24 20:58



Yah demi kewarasan. Pastikan ordinal Anda sama dalam gaya yang Anda deklarasikan seperti dalam deklarasi Enum Anda dan akses sebagai larik.

TypedArray a = context.getTheme().obtainStyledAttributes(
                   attrs,
                   R.styleable.IconView,
                   0, 0);

int ordinal = a.getInt(R.styleable.IconView_icon, 0);

if (ordinal >= 0 && ordinal < MyEnum.values().length) {
      enumValue = MyEnum.values()[ordinal];
}

9
2018-03-04 21:52



Saya tahu ini sudah lama sejak pertanyaan itu diposting, tetapi saya memiliki masalah yang sama baru-baru ini. Saya meretas sedikit sesuatu bersama-sama yang menggunakan Square's JavaPoet dan beberapa hal di build.gradle yang secara otomatis membuat kelas enum Java dari attrs.xml pada build proyek.

Ada sedikit demo dan readme dengan penjelasan di https://github.com/afterecho/create_enum_from_xml

Semoga itu membantu.


2
2018-06-10 21:56