在运行新的preference支持库主题不正确 [英] New Preference support library incorrect theme at runtime

本文介绍了在运行新的preference支持库主题不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用新的preference V14支持库。为了让preferences材料的风格,我使用下面的风格对我的活动:

I'm trying to use the new Preference v14 Support library. To give the preferences a material style, I use the following style on my Activity:

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

这工作正常。我的问题是,当我在运行时添加新的preferences,它们会用一个旧的主题充气。下面是结果的截图:

That works fine. My problem is that when I add new Preferences at runtime, they get inflated using an old theme. Here's a screenshot of the result:

正如你可以看到,第一个preference,通过XML增加,有新的材质风格,而有的则没有。

As you can see, the first preference, added via XML, has the new Material style, while the others don't.

你有没有对如何解决这个问题的任何暗示?

Do you have any hint on how to solve the problem?

修改
这里是code的一个例子,我用它来在运行​​时添加了preference:

EDIT Here's an example of code I use to add the Preference at Runtime:

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

推荐答案

这个问题,你面对,是关系到上下文和如何将其主题化的作品。您code。通过传递 getActivity()来构造检索方面,但是,这是不是你想要的内容。下面是应用正确的方式解决方法:

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

说明

下面是的的onCreate(...)方法 preferenceFragmentCompat

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 正在从活动的主题检索。如果存在(即主题不为0), PFC 的( preferenceFragmentCompat )创建一个新的主题包装,将包含造型的相关信息:

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

使用这种风格的情况下,的 PFC 的现在可以创建一个 preferenceManager

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

此的 PFC 的的的的风格是现在 preferenceTheme 包含所有不同子样式( preferenceStyle 为例)。

This PFC's root style is now the preferenceTheme which contains all the different sub-styles (preferenceStyle for example).

您的解决方案的问题是, preference 类是寻找一个 preferenceStyle 属性中的构造器 - 通过上下文。然而,这只是在定义了 preferenceTheme ,而不是在活动的主题。

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.

这篇关于在运行新的preference支持库主题不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆