5

我正在尝试使用新的 Preference v14 Support 库。为了给偏好一种材料风格,我在我的活动中使用以下风格:

<style name="PreferenceTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
    <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>

这很好用。我的问题是,当我在运行时添加新首选项时,它们会使用旧主题膨胀。这是结果的屏幕截图:

跆拳道

如您所见,通过 XML 添加的第一个首选项具有新的 Material 样式,而其他首选项则没有。

您对如何解决问题有任何提示吗?

编辑 这是我用来在运行时添加首选项的代码示例:

import android.support.v7.preference.ListPreference;

for (...) {
        final ListPreference p = new ListPreference(getActivity());
        p.setTitle(name);
        p.setSummary(langname);
        p.setEntryValues(langEntryValues);
        p.setEntries(langDisplayValues);
        p.setDialogTitle(R.string.select_language);

        category.addPreference(p);
    }

PS:同样的行为发生在android.support.v7.preference.Preference

4

1 回答 1

17

您面临的问题Context与其主题化的工作方式及其工作方式有关。您的代码通过传递给构造函数来检索上下文getActivity(),但是,这不是您想要的上下文。这是应用正确样式的解决方案:

final Context ctx = getPreferenceManager().getContext();

for (...) {
    final ListPreference p = new ListPreference(ctx);
    // [...]

    category.addPreference(p);
}

解释

方法如下PreferenceFragmentCompatonCreate(...)

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);
    }
}

重要的几行:

this.getActivity().getTheme().resolveAttribute(attr.preferenceTheme, tv, true);
int theme = tv.resourceId;

这里preferenceTheme是从 Activity 的主题中检索的。如果它存在(即theme不为 0),PFC ( PreferenceFragmentCompat) 创建一个新的主题包装器,其中将包含样式信息:

this.mStyledContext = new ContextThemeWrapper(this.getActivity(), theme);

使用这种样式化的上下文,PFC现在可以创建PreferenceManager

this.mPreferenceManager = new PreferenceManager(this.mStyledContext);

这个PFC样式现在是preferenceTheme包含所有不同子样式(preferenceStyle例如)的。

您的解决方案的问题是该类正在构造函数传递的上下文中Preference寻找一个属性。preferenceStyle但是,它仅在您的 中定义preferenceTheme,而不是在 Activity 的主题中。

于 2015-09-08T12:30:51.700 回答