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