Android:如何获取当前主题的资源ID?

在Android中,您可以从getTheme()中将当前主题的活动作为Resource.Theme对象获取。 另外,您可以通过其他主题的资源ID将主题设置为不同的主题,如setTheme(R.style.Theme_MyTheme)

但是我怎样才能知道这是否值得呢?当前的主题是否已经是我想要设定的主题了? 我正在寻找类似getTheme().getResourceId()东西,以便写下如下所示的内容:

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

有任何想法吗?

OK,这里有一个难题:我们可以在AndroidManifest.xml中获取默认的主题,如context.getApplicationInfo().theme在应用程序级别设置的主题,以及从一个Activity内部getPackageManager().getActivityInfo(getComponentName(), 0).theme这个活动。

我想这给了我们一个起点,为自定义的getTheme()setTheme()做封装。

仍然感觉就像在解决 API问题一样。 所以我会留下这个问题,看看有人提出一个更好的主意。

我find了一种方法来解决这个需求,而不需要获取资源ID。

我使用string的名称为每个主题添加一个项目:

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

而在代码中,我检查这样的名字:

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

有一种方法可以通过reflection来做到这一点。 把这个放在你的Activity中:

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

[在此处插入关于非公开API的免责声明]

根据Activity.setTheme的来源调用Activity.onCreate之前,所以你可以保存themeId当android设置它:

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