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

mar*_*c1s 61 android

在Android中,您可以将活动的当前主题作为Resource.Theme对象获取getTheme().此外,您可以通过其他主题的资源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
    }
}
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

mar*_*c1s 42

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

我想这给了我们一个起点,为自定义getTheme()和自己做包装setTheme().

还是那个感觉就像工作周围,而不是的API.所以我会留下问题,看看是否有人提出了更好的主意.

编辑:

getPackageManager().getActivityInfo(getComponentName(), 0).getThemeResource()
Run Code Online (Sandbox Code Playgroud)

如果活动没有覆盖它,它将自动回退到应用程序主题.

  • 在`Context`上有一个`getThemeResId()`方法但不幸的是它不公开:-( (20认同)

mar*_*mor 39

我找到了一种在不获取资源ID的情况下解决需求的方法.

我正在使用字符串的名称为我的每个主题添加一个项目:

<item name="themeName">dark</item>
Run Code Online (Sandbox Code Playgroud)

在代码中我检查名称如下:

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

  • <! - 必须在attr.xml文件中添加一个主题名称引用才能使用它,但它可以工作;) - > <attr name ="themeName"format ="string"/> (4认同)
  • 这是一个非常有创意的想法。谢谢! (4认同)

Kar*_*uri 10

有一种方法可以通过反射来做到这一点.把它放在你的活动中:

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 ...
Run Code Online (Sandbox Code Playgroud)

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


Dem*_*n13 7

根据消息来源, Activity.setTheme在Activity.onCreate之前被调用,因此您可以在设置android时保存themeId:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)