Android – the new preference library supports incorrect themes at runtime

I'm trying to use the new preference V14 support library. In order to provide material styles for preferences, I use the following styles on the activity:

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

That's good. My problem is that when I add new preferences at runtime, they expand with the old theme. This is a screenshot of the result:

As you can see, the first preference added through XML has a new material style, while the other preferences do not

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

Edit this is my code example for adding preference at run time:

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 has the same behavior

resolvent:

The problem you face is related to the working principle of context and its topic. Your code retrieves the context by passing getactivity () to the constructor, but this is not the context you want. Here is the solution to apply the correct style:

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

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

    category.addPreference(p);
}

explain

This is the oncreate (...) method of 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);
    }
}

Important routes:

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

Here is to retrieve the preferred theme from the theme of the activity. If it exists (i.e. the theme is not 0), PFC (preferencefragmentcompat) will create a new theme wrapper containing style information:

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

With this stylized context, PFC can now create a preferencemanager:

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

The root style of this PFC is now the preferred theme, and it contains all the different sub styles (such as preferencestyle)

The problem with your solution is that the preference class looks for the preferencestyle property in the context passed by the constructor. However, it is only defined in your preference topic, not in the active topic

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>