The problem, you're facing, is related to Context
and how its theming works. Your code retrieves a context by passing getActivity()
to the constructor, however, this is not the context you want. Here's the solution that applies the correct styles:
final Context ctx = getPreferenceManager().getContext();
for (...) {
final ListPreference p = new ListPreference(ctx);
// [...]
category.addPreference(p);
}
Explanation
Here's PreferenceFragmentCompat
's onCreate(...)
method:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TypedValue tv = new TypedValue();
this.getActivity().getTheme().resolveAttribute(attr.preferenceTheme, tv, true);
int theme = tv.resourceId;
if(theme <= 0) {
throw new IllegalStateException("Must specify preferenceTheme in theme");
} else {
this.mStyledContext = new ContextThemeWrapper(this.getActivity(), theme);
this.mPreferenceManager = new PreferenceManager(this.mStyledContext);
// [...]
this.onCreatePreferences(savedInstanceState, rootKey);
}
}
The important lines:
this.getActivity().getTheme().resolveAttribute(attr.preferenceTheme, tv, true);
int theme = tv.resourceId;
Here the preferenceTheme
is being retrieved from the Activity's theme. If it exists (i.e. theme
is not 0), PFC (PreferenceFragmentCompat
) creates a new theme wrapper which will contain the styling infos:
this.mStyledContext = new ContextThemeWrapper(this.getActivity(), theme);
Using this styled context, the PFC can now create the PreferenceManager
:
this.mPreferenceManager = new PreferenceManager(this.mStyledContext);
This PFC's root style is now the preferenceTheme
which contains all the different sub-styles (preferenceStyle
for example).
The problem with your solution is that the Preference
class is looking for a preferenceStyle
attribute in the contructor-passed context. However, it's only defined in your preferenceTheme
, not in the Activity's theme.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…