Подтвердить что ты не робот

Android: Как получить идентификатор ресурса текущей темы?

В Android вы можете получить текущую тему активности как объект Resource.Theme из getTheme(). Кроме того, вы можете установить тему на другую с помощью другого идентификатора ресурса темы, как в 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
    }
}

Любые идеи?

4b9b3361

Ответ 1

OK вот одна часть головоломки: мы можем получить тему по умолчанию, как установлено в AndroidManifest.xml, как context.getApplicationInfo().theme для темы, установленной на уровне приложения, и изнутри Activity, as getPackageManager().getActivityInfo(getComponentName(), 0).theme для этой активности.

Я думаю, это дает нам отправную точку для создания собственной оболочки для пользовательских getTheme() и setTheme().

Тем не менее, это похоже на работу, а не на API. Поэтому я оставлю вопрос открытым, чтобы узнать, появляется ли у кого-то лучшая идея.

Ответ 2

Я нашел способ решить требование без получения идентификатора ресурса.

Я добавляю элемент к каждой из моих тем с именем строки:

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

И в коде я проверяю имя так:

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

Ответ 3

Есть способ сделать это через отражение. Поместите это в свою деятельность:

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

[Вставить опровержение здесь относительно непубличного apis]

Ответ 4

В соответствии с sources Activity.setTheme вызывается перед Activity.onCreate, поэтому вы можете сохранить темуId, когда 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;
    }
}