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
}
}
Любые идеи?
Ответы
Ответ 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;
}
}