2013-08-22 23 views
65

Utworzono niestandardowy widok (znajdź here) z atrybutem typu enum, który można stylować w stylu deklaracji. W xml mogę teraz wybrać jedną z pozycji wyliczeniowych dla mojego niestandardowego atrybutu. Teraz chcę utworzyć metodę, aby ustawić tę wartość programowo, ale nie mam dostępu do wyliczenia.Jak uzyskać wyliczenie, które jest tworzone w pliku attrs.xml w kodzie

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

Co potrzebne jest coś takiego: mCustomView.setIcon(R.id.enum_name_x); Ale nie mogę znaleźć wyliczenia albo ja nawet nie mam pojęcia jak mogę uzyskać enum lub nazwy enum.

Dzięki

Odpowiedz

63

Tam nie wydaje się być zautomatyzowane sposób, aby uzyskać enum Java z wyliczenia atrybutu - w Javie można uzyskać wartość liczbową podałeś - ciąg jest do stosowania w plikach XML (jak ty pokazać).

Można to zrobić w widoku konstruktora:

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(); 
} 

Jeśli chcesz wartości do wyliczenia będzie trzeba albo map wartość w Javie ENUM siebie, np

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(); 
    } 
} 

Następnie w pierwszym bloku kodu można użyć:

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

(choć rzuca wyjątek w tym p oint może nie być świetnym pomysłem, prawdopodobnie lepiej wybrać rozsądną wartość domyślną)

7

Cóż dla zdrowia psychicznego. Upewnij się, że liczby porządkowe są takie same w zadeklarowanym stylu, jak w deklaracji Enum i uzyskaj dostęp do niej jako tablicy.

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]; 
} 
+0

Myślę, że poleganie tutaj na enum ordinals ma na celu stworzenie niewiarygodnego kodu. Jedna rzecz zostanie zaktualizowana, a nie druga, a wtedy będziesz miał kłopoty. – tir38

2

Wiem, że minęło trochę czasu od opublikowania pytania, ale ostatnio miałem ten sam problem. Zrobiłem trochę razem, używając JavaPoet Square i trochę rzeczy z build.gradle, które automatycznie tworzą klasę enum Java z pliku attrs.xml na kompilacji projektu.

Jest trochę demo i readme z wyjaśnieniem w https://github.com/afterecho/create_enum_from_xml

Nadzieję, że to pomaga.