PreferenceFragmentCompat - Must specify preferenceTheme in theme

De-Bill

Сразу оговорюсь, решения с английского SO мне не помогли. Пробовал Это, это, и это,

Ну, обо всем по порядку:

Решил уйти от связки PreferenceActivity + PreferenceFragment оставив только PreferenceFragment, сначала юзал PreferenceFragment из системы, но он наслаивался на фрагменты из библиотеки поддержки, рисовал себя поверх интефейса.

Мне такое поведение не понравилось, и я решил попробовать PreferenceFragmentCompat, из библиотеки android.support.preference-v7, версии 25.3.1

compile "com.android.support:preference-v7:${supportLibVersion}"

Транзакция фрагмента такова:

getSupportFragmentManager().popBackStack();
                    getSupportFragmentManager()
                            .beginTransaction()
                            .replace(R.id.frame_container, new SettingsFragment())
                            .commit();

Но при запуске фрагмента я получаю такую ошибку

java.lang.IllegalStateException: Must specify preferenceTheme in theme

У меня 2 темы, в них я указал этот атрибут: <item name="preferenceTheme">@style/PreferenceThemeOverlay</item> Ошибка не изчезла, попробовал использовать фикс-библиотеку compile 'com.takisoft.fix:preference-v7:25.3.1.0' все то же самое. Попробовал задать свой стиль -- бесполезно.

Код фрагмента с фикс библиотекой:

public class SettingsFragment extends PreferenceFragmentCompat {
    SharedPreferences preferences;

    @Override
    public void onCreatePreferencesFix(Bundle savedInstanceState, String pref) {
        super.onCreate(savedInstanceState);
        preferences =  PreferenceManager.getDefaultSharedPreferences(getActivity());
        setPreferencesFromResource(R.xml.setting, pref);
        setHasOptionsMenu(true);

        Preference ThemePref = findPreference("ITheme.Theme");
        if (ThemePref != null) {
            ThemePref.setOnPreferenceClickListener(preference -> {
                try {
                    String[] items = new String[]{"LIGHT", "DARK"};
                    new MaterialDialog.Builder(getActivity())
                            .items(items)
                            .itemsCallback((dialog, view, i, items1) -> {
                                switch (i) {
                                    case 0://LIGHT
                                        preferences.edit().putInt("ITheme.Theme", ThemeInterfacer.LIGHT).apply();
                                        ThemeInterfacer.setAppTheme(getActivity(), ThemeInterfacer.LIGHT);
                                        break;
                                    case 1://DARK
                                        preferences.edit().putInt("ITheme.Theme", ThemeInterfacer.DARK).apply();
                                        ThemeInterfacer.setAppTheme(getActivity(), ThemeInterfacer.DARK);
                                        break;
                                    default:
                                        break;
                                }
                            })
                            .show();
                    return true;
                } catch (Throwable throwable) {
                    Toasty.error(getActivity(), Arrays.toString(throwable.getStackTrace()), Toast.LENGTH_LONG, false).show();
                    throwable.printStackTrace();
                }
                return false;
            });
        }
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, ************ inflater) {
        if (menu != null) {
            menu.clear();
        } else
            menu = new MenuBuilder(getActivity());
        menu.add("Test").setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS);
    }

}

styles.xml

<resources>

    <!--Global app Styles-->
    <!-- Base application theme. -->
    

    

    

    

    

    

    

    

    

    

    

    

    

    <!--Toolbar Style-->
    
    
    
    
    
    
    
    

</resources>

StackTrace

java.lang.IllegalStateException: Must specify preferenceTheme in theme
at android.support.v7.preference.PreferenceFragmentCompat.onCreate(PreferenceFragmentCompat.java:210)
at com.takisoft.fix.support.v7.preference.PreferenceFragmentCompat.onCreate(PreferenceFragmentCompat.java:34)
at android.support.v4.app.Fragment.performCreate(Fragment.java:2180)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1244)
at android.support.v4.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1085)
at android.support.v4.app.FragmentTransition.calculateFragments(FragmentTransition.java:976)
at android.support.v4.app.FragmentTransition.startTransitions(FragmentTransition.java:95)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2146)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2103)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2013)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:710)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6178)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)

У меня уже матерных слов не хватает

1 ответ

De-Bill

Крайне неохота разбираться в вашем коде, просто приведу выдержку из своих стилей с декларацией стилей для PreferenceFragmentCompat

Надеюсь идея понятна. По сути идет отсылка к системной теме: @style/PreferenceThemeOverlay.v14.Material, которая и обеспечивает наличие нужной темы.

licensed under cc by-sa 3.0 with attribution.