2011-09-01 29 views
45

Trong Android, bạn có thể lấy chủ đề hiện tại của một hoạt động dưới dạng đối tượng Resource.Theme từ getTheme(). Ngoài ra, bạn có thể đặt chủ đề thành một chủ đề khác thông qua id tài nguyên của chủ đề khác, như trong setTheme(R.style.Theme_MyTheme).Android: Cách lấy ID tài nguyên của chủ đề hiện tại?

Nhưng làm cách nào để tìm hiểu xem nó có đáng giá không - liệu chủ đề hiện tại đã là chủ đề mà tôi muốn đặt chưa? Tôi đang tìm một cái gì đó như getTheme().getResourceId(), để viết một cái gì đó như:

protected void onResume() { 
    int newThemeId = loadNewTheme(); 
    if (newThemeId != getTheme().getResourceId()) { // !!!! How to do this? 
     setTheme(newThemeId); 
     // and rebuild the gui, which is expensive 
    } 
} 

Bất kỳ ý tưởng nào?

+0

Tôi không nghĩ ID tài nguyên là thuộc tính của lớp Chủ đề. Chủ đề có thể được tạo từ tệp xml nguồn lại, nhưng sau đó tham chiếu đến ID bị mất. Chủ đề chính nó có thể được thay đổi, và sau đó nó sẽ không có ý nghĩa để được gắn với một ID tài nguyên nhất định. Thậm chí nhiều hơn, chủ đề có thể được tạo ra trên bay trong mã. Bạn sẽ phải theo dõi ID nguồn tái sử dụng nào được sử dụng cho chính chủ đề hiện tại. – Anderson

+0

Câu trả lời này sẽ giúp bạn. Hãy kiểm tra http://stackoverflow.com/a/26302184/4639479 –

Trả lời

34

OK đây là một mảnh ghép: chúng tôi có thể nhận được mặc định chủ đề , như quy định trong AndroidManifest.xml, như context.getApplicationInfo().theme cho chủ đề đặt ở mức ứng dụng, và từ bên trong một hoạt động, như getPackageManager().getActivityInfo(getComponentName(), 0).theme cho hoạt động đó.

Tôi đoán điều đó cho chúng ta điểm khởi đầu để thực hiện trình bao bọc của riêng mình cho một tùy chỉnh getTheme()setTheme().

Vẫn cảm thấy như đang làm việc quanh thay vì với API. Vì vậy, tôi sẽ để câu hỏi mở ra để xem ai đó có ý tưởng hay hơn không.

+0

Cảm giác tương tự ở đây về vấn đề này và +1 cho việc tìm kiếm nó. –

+12

Có một phương thức 'getThemeResId()' trên 'Context' nhưng tiếc là nó không được công khai :-( –

27

Tôi đã tìm thấy cách để giải quyết yêu cầu mà không cần nhận id tài nguyên.

tôi thêm một mục cho mỗi chủ đề của tôi với tên của chuỗi:

<item name="themeName">dark</item> 

Và trong đoạn code tôi kiểm tra tên những thứ tương tự như vậy:

TypedValue outValue = new TypedValue(); 
getTheme().resolveAttribute(R.attr.themeName, outValue, true); 
if ("dark".equals(outValue.string)) { 
    ... 
} 
+1
+1

Đó là một ý tưởng thực sự sáng tạo. Cảm ơn! – LoungeKatt

7

Có một cách để làm điều này thông qua sự phản ánh. Đặt điều này trong hoạt động của bạn:

int themeResId = 0; 
try { 
    Class<?> clazz = ContextThemeWrapper.class; 
    Method method = clazz.getMethod("getThemeResId"); 
    method.setAccessible(true); 
    themeResId = (Integer) method.invoke(this); 
} catch (NoSuchMethodException e) { 
    Log.e(TAG, "Failed to get theme resource ID", e); 
} catch (IllegalAccessException e) { 
    Log.e(TAG, "Failed to get theme resource ID", e); 
} catch (IllegalArgumentException e) { 
    Log.e(TAG, "Failed to get theme resource ID", e); 
} catch (InvocationTargetException e) { 
    Log.e(TAG, "Failed to get theme resource ID", e); 
} 
// use themeResId ... 

[Insert từ chối trách nhiệm ở đây liên quan đến apis ngoài công lập]

+0

Nó hoạt động tốt. –

3

Theo sources Activity.setTheme được gọi trước khi Activity.onCreate, vì vậy bạn có thể lưu themeId khi android cài đặt nó :

public class MainActivity extends Activity { 
    private int themeId; 

    @Override 
    public void setTheme(int themeId) { 
     super.setTheme(themeId); 
     this.themeId = themeId; 
    } 

    public int getThemeId() { 
     return themeId; 
    } 
} 
Các vấn đề liên quan