2013-08-22 38 views
65

Tôi đã tạo Chế độ xem tùy chỉnh (tìm thấy nó here) với thuộc tính có thể khai báo kiểu thuộc tính enum. Trong xml bây giờ tôi có thể chọn một trong các mục enum cho thuộc tính tùy chỉnh của tôi. Bây giờ tôi muốn tạo một phương thức để thiết lập giá trị này theo lập trình, nhưng tôi không thể truy cập vào enum.Làm thế nào để có được một enum được tạo ra trong attrs.xml trong mã số

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

Những gì tôi cần là một cái gì đó như: mCustomView.setIcon(R.id.enum_name_x); Nhưng tôi không thể tìm thấy enum hoặc tôi thậm chí không có ý tưởng làm thế nào tôi có thể nhận được enum hoặc tên của enum.

Cảm ơn

Trả lời

63

Hiện không có vẻ là một cách tự động để có được một enum Java từ một enum thuộc tính - trong Java bạn có thể lấy giá trị số mà bạn chỉ định - chuỗi là để sử dụng trong các tập tin XML (như bạn chỉ).

Bạn có thể làm điều này trong constructor xem của bạn:

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

Nếu bạn muốn các giá trị vào một enum bạn sẽ cần một trong hai bản đồ giá trị vào một Java enum mình, ví dụ:

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

Sau đó, trong khối mã đầu tiên bạn có thể sử dụng:

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

(mặc dù ném một ngoại lệ tại trang này oint có thể không phải là một ý tưởng tuyệt vời, có lẽ tốt hơn để chọn một giá trị mặc định hợp lý)

7

Vâng vì lợi ích của sanity. Hãy chắc chắn rằng các bộ phận của bạn giống nhau trong kiểu được khai báo của bạn như trong khai báo Enum của bạn và truy cập nó như là một mảng.

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

Tôi nghĩ rằng dựa vào các thử nghiệm enum ở đây là mệnh để tạo mã không đáng tin cậy. Một điều sẽ được cập nhật chứ không phải cái kia và bạn sẽ gặp rắc rối. – tir38

2

Tôi biết đã lâu rồi kể từ khi câu hỏi được đăng, nhưng gần đây tôi đã gặp vấn đề tương tự. Tôi đã hack một thứ gì đó với nhau sử dụng JavaPoet của Square và một số thứ trong build.gradle để tự động tạo một lớp enum Java từ tệp attrs.xml trên dự án.

Có một bản demo nhỏ và một readme với một lời giải thích tại https://github.com/afterecho/create_enum_from_xml

Hy vọng nó giúp.

Các vấn đề liên quan