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

wkyowqbh  于 2023-05-21  发布在  Android
关注(0)|答案(6)|浏览(205)

在Android中,您可以从getTheme()获取Activity的当前主题作为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
    }
}

有什么想法吗

rks48beu

rks48beu1#

我找到了一种无需获取资源ID即可解决需求的方法。
我在我的每个主题中添加一个项目,名称为字符串:

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

在代码中,我这样检查名称:

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

brvekthn2#

好了,这里有一个谜题:我们可以获取default主题,如AndroidManifest.xml中设置的,作为应用程序级别的主题集的context.getApplicationInfo().theme,以及从Activity中获取该Activity的getPackageManager().getActivityInfo(getComponentName(), 0).theme
我想这给了我们一个起点,为定制的getTheme()setTheme()做我们自己的 Package 器。
不过,这感觉就像是在 * 周围 * 工作,而不是 * 使用 * API。所以我会把这个问题留给大家,看看是否有人能想出更好的主意。

**编辑:**有

getPackageManager().getActivityInfo(getComponentName(), 0).getThemeResource()

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

epggiuax

epggiuax3#

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

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的免责声明]

68bkxrlz

68bkxrlz4#

根据消息来源,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;
    }
}
ivqmmu1c

ivqmmu1c5#

如果您在清单中的<activity/>元素中指定了android:theme="@style/SomeTheme",则可以像这样获取Activity主题的资源ID:

int themeResId;
try {
    PackageManager packageManager = getPackageManager();
    //ActivityInfo activityInfo = packageManager.getActivityInfo(getCallingActivity(), PackageManager.GET_META_DATA);
    ActivityInfo activityInfo = packageManager.getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
    themeResId = activityInfo.theme;
}
catch(PackageManager.NameNotFoundException e) {
    Log.e(LOG_TAG, "Could not get themeResId for activity", e);
    themeResId = -1;
}

别忘了,如果你要在Activity的**onCreate()**方法中调用setTheme(themeResId),你需要在调用setContentView(...)之前 * 执行它。

j7dteeu8

j7dteeu86#

重写方法“setTheme(int)”并将Id值保存在类中

private int myVariable;

@Override
public void setTheme(int themeId) {
    super.setTheme(themeId);
    //get the id resource
    myVariable = themeId;
}

相关问题