PreferenceFragmentCompat - Must specify preferenceTheme in theme

303
28 апреля 2017, 17:59

Сразу оговорюсь, решения с английского 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, MenuInflater 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. -->
    <style name="MaterialDrawerTheme.Light.DarkToolbar" parent="MaterialDrawerTheme.Light.TranslucentStatus">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="textButtonColor">@color/white</item>
        <item name="drawerBkg">@drawable/head</item>
        <item name="material_drawer_background">@color/material_drawer_dark_background</item>
        <item name="material_drawer_primary_text">@color/material_drawer_dark_primary_text</item>
        <item name="material_drawer_secondary_text">@color/material_drawer_dark_secondary_text
        </item>
        <item name="material_drawer_hint_text">@color/material_drawer_dark_hint_text</item>
        <item name="material_drawer_divider">@color/material_drawer_dark_divider</item>
        <item name="material_drawer_selected">@color/material_drawer_dark_selected</item>
        <item name="material_drawer_selected_text">#F1433C</item>
        <item name="material_drawer_header_selection_text">
            @color/material_drawer_dark_primary_text
        </item>
        <item name="preferenceTheme">@style/PreferenceThemeLight</item>
        <!-- CAB :D -->
        <item name="windowActionModeOverlay">true</item>
        <item name="cardBackgroundColor">@color/white</item>
    </style>
    <style name="MaterialDrawerTheme.TranslucentStatus" parent="MaterialDrawerTheme">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccentDark</item>
        <item name="android:textColorPrimaryInverseNoDisable">@color/colorAccentDark</item>
        <item name="textButtonColor">@color/light_silver</item>
        <item name="drawerBkg">@drawable/head_night</item>
        <item name="buttonTint">@color/colorAccentDark</item>
        <item name="cardBackgroundColor">@color/card_bg_dark</item>
        <item name="preferenceTheme">@style/PreferenceThemeLight</item>
    </style>
    <style name="MaterialDrawerTheme.Light.DarkToolbar.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="preferenceTheme">@style/PreferenceThemeLight</item>
    </style>
    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
    <style name="AppTheme.TableRow" parent="MaterialDrawerTheme.Light.DarkToolbar">
        <item name="buttonStyle" parent="?android:attr/buttonBarStyle">
            @style/Base.Widget.AppCompat.Button.Borderless.Colored
        </item>
        <item name="preferenceTheme">@style/PreferenceThemeLight</item>
    </style>
    <style name="AppTheme.Dialog" parent="Theme.AppCompat" />
    <style name="Settings" parent="Theme.AppCompat">
        <item name="preferenceTheme">@style/PreferenceThemeLight</item>
    </style>
    <style name="Settings.Light" parent="Theme.AppCompat.Light">
        <item name="preferenceTheme">@style/PreferenceThemeLight</item>
    </style>
    <style name="RGBPanelLabel" parent="@android:style/TextAppearance.Small">
        <item name="android:textColor">@color/dark_gray</item>
        <item name="android:textStyle">italic</item>
        <item name="android:fontFamily">sans-serif-light</item>
    </style>
    <style name="RGBPanelComponentLabel" parent="@android:style/TextAppearance.Medium">
        <item name="android:textColor">@color/dark_gray</item>
        <item name="android:fontFamily">sans-serif</item>
    </style>
    <style name="RGBPanelComponent" parent="@android:style/TextAppearance.Medium">
        <item name="android:textColor">@color/black</item>
        <item name="android:fontFamily">sans-serif-medium</item>
    </style>
    <style name="PaletteLight" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowBackground">@color/light_silver</item>
        <item name="cardBackgroundColor">@color/white</item>
        <item name="preferenceTheme">@style/PreferenceThemeLight</item>
    </style>
    <style name="PaletteDark" parent="Theme.AppCompat.NoActionBar">
        <item name="cardBackgroundColor">@color/card_bg_dark</item>
        <item name="preferenceTheme">@style/PreferenceThemeLight</item>
    </style>
    <style name="ProfileCardStyle" parent="CardView">
        <item name="android:layout_marginLeft">@dimen/card_margin_horizontal</item>
        <item name="android:layout_marginRight">@dimen/card_margin_horizontal</item>
        <item name="android:layout_marginBottom">8dp</item>
        <item name="cardCornerRadius">0dp</item>
        <item name="cardElevation">1dp</item>
        <item name="preferenceTheme">@style/PreferenceThemeLight</item>
    </style>
    <style name="PreferenceThemeLight" parent="@style/Theme.AppCompat">
        <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
        <item name="preferenceDialog_messageAppearance">@style/PreferenceFixTheme.TextAppearanceDialogMessage
        </item>
        <!-- Overriding the category views as they don't look good -->
        <item name="android:listSeparatorTextViewStyle">
            @style/PreferenceFixTheme.ListSeparatorTextView
        </item>
        <item name="android:textAppearanceLarge">@style/PreferenceFixTheme.TextAppearanceLarge
        </item>
        <item name="android:textAppearanceSmall">@style/PreferenceFixTheme.TextAppearanceSmall
        </item>
    </style>
    <!--Toolbar Style-->
    <style name="RedToolbar">
        <item name="colorPrimary">@color/red500</item>
        <item name="colorPrimaryDark">@color/red900</item>
        <item name="colorAccent">@color/red</item>
    </style>
    <style name="PinkToolbar">
        <item name="colorPrimary">@color/pink500</item>
        <item name="colorPrimaryDark">@color/pink900</item>
        <item name="colorAccent">@color/pink</item>
    </style>
    <style name="IndigoToolbar">
        <item name="colorPrimary">@color/indigo500</item>
        <item name="colorPrimaryDark">@color/indigo900</item>
        <item name="colorAccent">@color/indigo</item>
    </style>
    <style name="BlueToolbar">
        <item name="colorPrimary">@color/blue500</item>
        <item name="colorPrimaryDark">@color/blue900</item>
        <item name="colorAccent">@color/blue</item>
    </style>
    <style name="GreenToolbar">
        <item name="colorPrimary">@color/green500</item>
        <item name="colorPrimaryDark">@color/green900</item>
        <item name="colorAccent">@color/green</item>
    </style>
    <style name="AmberToolbar">
        <item name="colorPrimary">@color/ambera700</item>
        <item name="colorPrimaryDark">@color/amber900</item>
        <item name="colorAccent">@color/amber</item>
    </style>
    <style name="DeepOrangeToolbar">
        <item name="colorPrimary">@color/deep_orange500</item>
        <item name="colorPrimaryDark">@color/deep_orange900</item>
        <item name="colorAccent">@color/deep_orange500</item>
    </style>
    <style name="BlueGreyToolbar">
        <item name="colorPrimary">@color/blue_grey500</item>
        <item name="colorPrimaryDark">@color/blue_grey900</item>
        <item name="colorAccent">@color/blue_grey</item>
    </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)

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

Answer 1

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

<!-- Light application theme -->
<style parent="Theme.AppCompat.Light.DarkActionBar" name="AppTheme.Light">
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
<item name="android:alertDialogStyle">@style/TransparentAlertDialogStyle</item>
<item name="dialogTheme">@style/ControlDialogStyle.Light</item>
<item name="colorPrimary">@color/primaryColorLight</item>
<item name="colorPrimaryDark">@color/primaryColorDark</item>
<item name="cardStyle">@style/CardView.Light</item>
<item name="hintColor">@color/hintColorLight</item>
<item name="actionColor">@color/white</item>
<item name="android:dialogTheme">@style/ControlDialogStyle.Light</item>
</style>

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

READ ALSO
Законность парсинга сайтов [требует правки]

Законность парсинга сайтов [требует правки]

Есть один сайт, нужно "слить" весь контентСтруктура следующая : http://lenfilm

264
Error:Cause: unable to find valid certification path to requested target

Error:Cause: unable to find valid certification path to requested target

Добрый день, возникла проблема при клонировании проекта с GitHub, все сделал по инструкциямМожет ли кто объяснить в что я сделал не так? Версия...

265