PreferenceFragmentCompat wymaga ustawienia parametru PreferenceTheme


114

W przypadku nowego PreferenceFragmentCompat z biblioteki obsługi preferencji w wersji 7: http://developer.android.com/tools/support-library/features.html#v7-preference pojawia się ten błąd

E  java.lang.IllegalStateException: Must specify preferenceTheme in theme
E      at android.support.v7.preference.PreferenceFragmentCompat.onCreate(PreferenceFragmentCompat.java:202)

Jaki motyw ustawić?

Aktualizacja: próbowałem użyć

<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>

zgodnie z sugestią @Bogato, ale nie wygląda dobrze i wygląda bardzo Holo nawet na Lollipopie.

Biblioteka wsparcia:

wprowadź opis obrazu tutaj

Natywne preferencje:

wprowadź opis obrazu tutaj


2
Wystąpił błąd dotyczący dokumentacji do tego tutaj: code.google.com/p/android/issues/…
Intrications

1
Osobiście nie uważam, że te rozwiązania są warte obejścia. Wypróbuj github.com/kolavar/android-support-v4-preferencefragment
MidasLefko

1
Czy możesz oznaczyć stackoverflow.com/a/44236460/238753 jako zaakceptowaną odpowiedź?
Sam

Odpowiedzi:


159

Przykładowy projekt można znaleźć tutaj

Poprawka jest dostępna jako zależność od gradle

Pobieranie

Teraz można łatwo korzystać z biblioteki. Oto najszybszy sposób, aby to zrobić, ale zapoznaj się z README, aby uzyskać więcej informacji.

1. Zaktualizuj plik gradle modułu:

compile 'com.takisoft.fix:preference-v7:27.0.0.0'

2. Użyj odpowiedniej klasy jako podstawy swojego fragmentu

Możesz użyć albo PreferenceFragmentCompatlub PreferenceFragmentCompatDividers.

( Uważaj na odpowiednią nazwę pakietu podczas importowania PreferenceFragmentCompat! )

3. Użyj odpowiedniego motywu

Ustaw motyw zawierający działanie na wariant @style/PreferenceFixTheme, taki jak NoActionBar, Light itp.

Aby uzyskać więcej informacji i wskazówek dotyczących użytkowania, przejdź do strony projektu .


PS W tej sekcji można było znaleźć szczegółowe rozwiązanie, które doprowadziło do powstania biblioteki, ale zdecydowałem się ją usunąć, ponieważ może to być mylące. Jeśli jesteś ciekawy kroków, nadal możesz je znaleźć w historii wersji tej odpowiedzi.


6
Domyślny rozmiar tekstu jest zbyt duży, próbowałem go zmodyfikować za pomocą tych stylów, które wskazałeś bez powodzenia. Czy udało Ci się dostosować rozmiar tekstu?
Tinashe

4
Próbuję umieścić tam materiał projektowy, ale nie do końca mi się to udało ... Podczas tego procesu odkryłem, że w pakiecie preferencji v7 brakuje stylu, układu i innych plików związanych z materiałami. W międzyczasie wersja 14 zawiera niektóre z nich, ale problem z wersją 14 polega na tym, że rozszerza ona fragment natywny, a nie wspierający. Myślę, że Google popełnił tutaj naprawdę duży błąd, mam nadzieję, że naprawią to jak najszybciej ...
Gergely Kőrössy

1
Mogę spróbować zastosować materiał projektowy również dla urządzeń sprzed 21 lat, teraz wyglądają tak samo jak oryginał.
Gergely Kőrössy

2
Należy również wspomnieć, że PreferenceFragmentCompat ulega awarii, jeśli jest obracany z otwartym oknem dialogowym. code.google.com/p/android/issues/detail?id=186160
headsvk

21
To jest niedorzeczne. Stworzenie fragmentu preferencji od zera zajęłoby mi mniej czasu niż znalezienie sposobu na przejście przez wszystkie błędy, obejścia i testy wymagane do tego, aby działał w 100% we wszystkich wersjach.
Edward van Raak,

46

Musisz określić preferenceTheme w motywie działania preferencji.

Na przykład :

<style name="SettingsTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>

PreferenceThemeOverlay jest domyślnym motywem, który zawiera bibliotekę obsługującą preferencje v7.


14
To działa, ale wygląda źle. Czcionki elementów preferencji są zbyt duże (testowane na Androidzie 4.1 i 5.1).

@ mus65 To jest problem. Domyślałem się, że powinienem użyć tego motywu, ale wygląda źle. Dodałem więcej szczegółów do pierwotnego pytania.
Intrications

3
Wybrałem to jako poprawną odpowiedź, ponieważ była to pierwsza, która podała prawidłowy temat do ustawienia. Jednak biblioteka wsparcia musi zostać naprawiona, aby preferencje korzystały z projektowania materiałów zgodnie z code.google.com/p/android/issues/detail?id=183376
Intrications

Jak nadać motywowi wygląd materiału? Obecnie pokazuje mi natywny wygląd ...
programista Androida,

1
Przeczytaj moją odpowiedź poniżej.
Gergely Kőrössy

35

Wygląda na to, że Google naprawił ten problem. Przetestowałem to z preferencją obsługi wersji 14 w wersji 25.3.1

1) Dodaj implementation 'com.android.support:preference-v14:25.3.1'do swojego Gradle.

2) Dodaj PreferenceThemeOverlay.v14.Materialdo stylu zamiastPreferenceThemeOverlay .

<style name="AppTheme.SettingsTheme" parent="AppTheme.NoActionBar">
    <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>

3) Na koniec dodaj styl do Manifestu

android:theme="@style/AppTheme.SettingsTheme"

Jedynym problemem związanym z tą odpowiedzią jest to, że fragment preferencji będzie używał motywu material w systemach z systemem KitKat i starszymi. Ustawianie preferenceThemesię PreferenceThemeOverlay.v14w styles.xmloraz PreferenceThemeOverlay.v14.Materialw styles-v21.xmlrozwiązuje problem.
Jack Meister,

@JackMeister, powinieneś używać wersji v14 tylko, jeśli docelowy poziom api wynosi 14 lub wyższy. Niezgodność motywu ze starszymi wersjami może nie być jedynym problemem, gdy używasz wersji 14 ze starszymi poziomami API.
Jelmer Brands

@JelmerBrands Jasne: nie powinieneś używać biblioteki obsługującej wersję 14 w systemach z poziomami API poniżej 14. Mój komentarz zakłada minSdkVersionmiędzy 14 a 20.
Jack Meister

Testowane w wersji 23.4.0, która działa równie dobrze. Kluczem jest użycie preferencji v14, a nie v7-preferencji.
user149408

14

Aby użyć PreferenceFragmentCompat , musisz ustawić preferenceThemew swoim motywie:

<style name="AppTheme" parent="@style/Theme.AppCompat.Light">
  ...
  <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>

W ten sposób możesz dostosować preferenceThemestyl układów używanych dla każdego typu preferencji bez wpływu na inne części działania.


Upewnij się, że dodajesz preferenceTheme do odpowiedniego stylu, który jest ustawiony jako motyw Twojej aktywności stackoverflow.com/a/40736138/1572286
Youness

14

Właśnie dodałem tę linię w motywie i działa idealnie na API 19 i nowszych.

<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>

3
To najprostsze, działające rozwiązanie, które nie wymaga dodatkowych zależności. Powinna być akceptowana odpowiedź IMHO, teraz, gdy większość aplikacji ma min API 14+
Louis CAD

Studio Android nie może tego znaleźć
Denny

3
dodaj com.android.support:preference-v14: to build.gradle
Sofi Software LLC

3

Rozwiązanie, które działało dla mnie w API 25. Miałem ten domyślny motyw:

<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

I dodał do tego tę linię

<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>

PreferenceThemeOverlay został już zdefiniowany, nie musiałem go uwzględniać. Działało na moich własnych urządzeniach z Androidem 4.xi 5.x.


2

Dodaj ten kod do pliku styles.xml i odpowiednio go zmodyfikuj. Powinno działać dobrze.

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>

<style name="PreferenceThemeOverlay">
    <item name="preferenceScreenStyle">@style/Preference.PreferenceScreen</item>
    <item name="preferenceFragmentStyle">@style/PreferenceFragment</item>
    <item name="preferenceCategoryStyle">@style/Preference.Category</item>
    <item name="preferenceStyle">@style/Preference</item>
    <item name="preferenceInformationStyle">@style/Preference.Information</item>
    <item name="checkBoxPreferenceStyle">@style/Preference.CheckBoxPreference</item>
    <item name="switchPreferenceCompatStyle">@style/Preference.SwitchPreferenceCompat</item>
    <item name="dialogPreferenceStyle">@style/Preference.DialogPreference</item>
    <item name="editTextPreferenceStyle">@style/Preference.DialogPreference.EditTextPreference</item>
    <item name="preferenceFragmentListStyle">@style/PreferenceFragmentList</item>
</style>


1

Dodałem element „preferenceTheme” do mojego stylu i wydawało się, że rozwiązało to problem:

   <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
     <item name="android:actionBarStyle">@style/MyActionBarTheme</item>
     <item name="colorPrimary">@color/ColorPrimary</item>
     <item name="colorPrimaryDark">@color/ColorPrimaryDark</item>
     <item name="preferenceTheme">@style/Preference</item>
 </style>

1

Najbardziej pomocna strona dla mnie: Medium

Autor pokazuje, że musimy dodać dwa pakiety: com.android.support:preference-v7icom.android.support:preference-v14 , ponieważ pierwszy jest rozprowadzany bez stylów.

Daj znać czy działa


0

Zaakceptowany „Takisoft Fix” wydaje się raczej niezdarny i po zabawie z nim nadal nie jestem zadowolony z uzyskanego wyglądu.

Jeśli potrzebujesz PreferenceFragmentbiblioteki obsługi API 9+ , polecam skorzystanie z biblioteki obsługi preferencji materiałów . Działa idealnie (przynajmniej dla mnie).


0

Ten problem występuje, ponieważ AAPT (Android Asset Packaging Tool) nie może znaleźć niektórych zasobów. Rozwiąż ten problem w następujący sposób:

1. Skopiuj zasoby, które są niezbędne do nowego odpowiadającego folderu zasobów, nazwanego jak res_fw_v7_preference lub innego.

2. Użycie gradle do zbudowania aplikacji i dodanie kilku dodatkowych opcji AAPT do build.gradle (modułów) w następujący sposób:

android {
    ...
    aaptOptions {
        additionalParameters '-S',
            'src/main/res_fw_v17_leanback',  // resources in frameworks/support/v17/leanback
            '-S',
            'src/main/res_fw_v7_preference',  // resources in frameworks/support/v7/preference
            '-S',
            'src/main/res_fw_v14_preference',  // resources in frameworks/support/v14/preference
            '-S',
            'src/main/res_fw_v17_preference-leanback',  // resources in frameworks/support/v17/preference-leanback
            '-S',
            'src/main/res_fw_v7_appcompat',  // resources in frameworks/support/v7/appcompat
            '-S',
            'src/main/res_fw_v7_recyclerview',  // resources in frameworks/support/v7/recyclerview
            '-S',
            'src/main/res',  // resources in your application
            '--auto-add-overlay',
            '--extra-packages',
            'android.support.v17.leanback:android.support.v7.preference:android.support.v14.preference:android.support.v17.preference:android.support.v7.appcompat:android.support.v7.recyclerview'
    noCompress 'foo', 'bar'
    ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~'
    }
    ...
}

Mam nadzieję, że to jest pomocne :)


0

Dzięki @sergio za odpowiedź, używanie <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>zamiast <item name="preferenceTheme">@style/Preference</item>działa świetnie dla mnie.

<style name="IntentTheme" parent="Theme.AppCompat">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:actionModeBackground">@color/fulltransparent</item>
        <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>

-8

Po prostu odpuść i użyj API 11+.

API 7 ma już prawie siedem lat.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.