Существует еще более простое решение, если вы в порядке, используя черную магию для достижения этой цели ...
Глядя на источник PreferenceScreen#showDialog(Bundle)
, мы видим, что диалог создается с использованием ресурса темы, полученного с помощью mContext.getThemeResId()
, который затем используется в ContextThemeWrapper
.
Это может существенно помочь нам, потому что Context
, используемый в PreferenceScreen
, на самом деле является нашим PreferenceActivity
, поэтому все, что нам нужно сделать, это переопределить метод getThemeResId()
(который скрыт от публичного API) , чтобы предоставить нашу пользовательскую тему, и под-PreferenceScreen теперь использует любой ресурс пользовательской темы, который мы хотели!
/**
* This is a hack to provide our own theme for the PreferenceScreen's dialog.
*
* @see android.preference.PreferenceScreen#showDialog(Bundle)
*/
public int getThemeResId() {
return R.style.Theme_MyApp_PreferenceScreen;
}
Обратите внимание, что, поскольку этот метод аннотирован @hide
, мы не можем использовать аннотацию @Override
, которая обычно используется в этом случае; и мы также не можем вызвать метод super.getThemeResId()
. Если вы действительно, действительно хотите иметь возможность условно переопределить это и обратиться к супер реализации в качестве запасного варианта, вам придется использовать Reflection, чтобы перейти к методу супер реализации:
try {
((Object) this).getClass().getMethod("getThemeResId").invoke(this);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}