PreferenceFragmentCompat requires preferenceTheme to be set

57,193

Solution 1

The sample project can be found here

The bugfix is available as a gradle dependency

Download

Now one can use the library pretty easy. Here are quickest way to do so, but you should check out the README for more info.

1. Update your module's gradle file:

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

2. Use the appropriate class as your fragment's base

You can use either PreferenceFragmentCompat or PreferenceFragmentCompatDividers.

(Watch out for the appropriate package name when importing PreferenceFragmentCompat!)

3. Use the appropriate theme

Set your containing Activity's theme to a variant of @style/PreferenceFixTheme, like NoActionBar, Light, etc.

For more info and usage tips, go to the project's page.


P.S. In this section you could find the detailed solution that led to creation of the library, but I decided to remove it because it might be confusing. If you're curious about the steps, you can still find them in the revision history of this answer.

Solution 2

You have to specify preferenceTheme in your preference activity's theme.

For example :

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

PreferenceThemeOverlay is the default theme which comes with preference-v7 support library.

Solution 3

Seems like Google fixed this issue. I've tested this with the preference v14-support version 25.3.1

1) Add implementation 'com.android.support:preference-v14:25.3.1' to your Gradle.

2) Add PreferenceThemeOverlay.v14.Material to the style instead of PreferenceThemeOverlay.

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

3) Finally, add the style to the Manifest

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

Solution 4

To use the PreferenceFragmentCompat you have to set preferenceTheme in your theme:

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

In this way you can customize the preferenceTheme to style the layouts used for each preference type without affecting other parts of your Activity.

Solution 5

I just added this line in theme and it working perfect on API 19 and above.

<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
Share:
57,193

Related videos on Youtube

Igoussam
Author by

Igoussam

Mobile App Developer

Updated on May 17, 2020

Comments

  • Igoussam
    Igoussam about 4 years

    With the new PreferenceFragmentCompat from the v7 Preference Support Library: http://developer.android.com/tools/support-library/features.html#v7-preference, I get this error

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

    What theme should be set?

    Update: I have tried using

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

    as suggested by @Bogato but it doesn't look right and looks very Holo even on Lollipop.

    Support library:

    enter image description here

    Native preferences:

    enter image description here

  • Admin
    Admin almost 9 years
    This works, but it looks wrong. The fonts of the preference elements are too big (tested on android 4.1 and 5.1).
  • Igoussam
    Igoussam almost 9 years
    @mus65 That's the problem. I had guessed I should use that theme but it looks bad. I've added more details to the original question.
  • Tinashe
    Tinashe almost 9 years
    The default text size is too big, I tried modifying it using these styles you pointed out without success. Did you perhaps manage to adjust text size?
  • Igoussam
    Igoussam almost 9 years
    This produces the same result as just using Bogato's answer of setting <item name="preferenceTheme">@style/PreferenceThemeOverlay</item> directly in the theme. As @Tinashe says, the styles are incorrect.
  • Gergely Kőrössy
    Gergely Kőrössy almost 9 years
    I'm trying to put the material design in there, but not really successful... What I discovered during the process is that the v7 preference pack is completely missing the material themed style, layout and other files. Meanwhile, the v14 contains some of them, but the problem with the v14 is that it extends the native Fragment, not the support one. I think Google just did a really big mistake here, hopefully they fix it asap...
  • Igoussam
    Igoussam almost 9 years
    @GergelyKőrössy Thanks for the update sample. Works fine for me. Seems like it should be easy for the support library to be fixed.
  • Gergely Kőrössy
    Gergely Kőrössy almost 9 years
    I might try to put the material design in place for pre-21 devices as well, they look the same as the original now.
  • Igoussam
    Igoussam almost 9 years
    I have selected this as the correct answer because it was the first one that said the correct theme to set. However the support library does need to be fixed so that the preferences use material design according to code.google.com/p/android/issues/detail?id=183376
  • android developer
    android developer almost 9 years
    How do I make the theme look material-design? Currently it shows the native look for me...
  • Gergely Kőrössy
    Gergely Kőrössy almost 9 years
    Read my answer below.
  • Spotlight
    Spotlight almost 9 years
    Hi, I used the attribute @style/PreferenceThemeOverlay.v14.Material, but it works only on xml Preferences. When I try to create and add a preference at runtime, it has that horrific style. Do you know how to solve it?
  • Gergely Kőrössy
    Gergely Kőrössy almost 9 years
    Do you instantiate the old Preference class or the support one?
  • Spotlight
    Spotlight almost 9 years
    @GergelyKőrössy I used the new android.support.v7.preferences.Preference
  • Spotlight
    Spotlight almost 9 years
    @GergelyKőrössy I posted my own question, can you give it a look please?
  • petrsyn
    petrsyn almost 9 years
    The project Android-Support-Preference-V7-Fix has minSdkVersion: 16 I suppose it doesn't work on API level 10...
  • Gergely Kőrössy
    Gergely Kőrössy almost 9 years
    You can try, I don't think it has anything that would require higher API levels (of course you might have to move the current generic styles.xml to a more appropriate (i.e. version qualified) directory and create one for lower API levels). I didn't target below 16 just because I think that anything below that is obsolete.
  • petrsyn
    petrsyn almost 9 years
    When dependency 'com.android.support:preference-v14:23.0.1' is added, the manifest merger complains that minSdkVersion must be at least 14...
  • Gergely Kőrössy
    Gergely Kőrössy almost 9 years
    Well, yeah. Then you cannot use material theme and API level <14 together. Unfortunately the guys at Google don't really care / this is a low-priority task...
  • DarkLeafyGreen
    DarkLeafyGreen almost 9 years
    @GergelyKőrössy do you have an idea why there are no divider lines between the preference items?
  • Gergely Kőrössy
    Gergely Kőrössy almost 9 years
    It's a result of changing from ListView to RecyclerView. The devs told us they'll get these artifacts cleand up for the next major release.
  • Lumii
    Lumii over 8 years
    Thanks for providing a GitHub project to demonstrate the solution. It is very much useful to have a minimal workable example as solution.
  • Lumii
    Lumii over 8 years
    Btw, is there any way we can make this works, for API 10 and above?
  • Gergely Kőrössy
    Gergely Kőrössy over 8 years
    @CheokYanCheng the used PreferenceThemeOverlay.v14.Material preference theme is obviously for API 14+ devices so that one cannot be used on devices below that. However, my original approach (using custom layout files copied from the support project) might be used, with some additional changes. If there's a high demand, I might try to implement it, but it would be better if Google did that, even though they said that no one really cares about porting material styling for devices before API 14.
  • Lumii
    Lumii over 8 years
    In fact, i don't really care whether v10 is having material look. I am fine if v10 falls back to default look. Just that, by including v14 lib, i will get compilation error, if my min sdk is 10.
  • Gergely Kőrössy
    Gergely Kőrössy over 8 years
    Yeah, don't know why the guys at Google can't see the problem... I tested the latest 23.1.0 version and it does fix some of the bugs but lots of them are still there. The normal @style/PreferenceThemeOverlay still uses the old styles even on API 21+ devices.
  • Arubu
    Arubu over 8 years
    @GergelyKőrössy i have the same issue. The normal @style/PreferenceThemeOverlay still uses the old styles even on API 21+ devices. Can it exist a workaround for this? I have tried all tips wrote in this thread.
  • Gergely Kőrössy
    Gergely Kőrössy over 8 years
    @Arubu The only solution (besides waiting for Google to fix it - but looks like they won't) is to implement a custom PreferenceTheme that uses appropriate layout files and material styles on the given platforms.
  • Gergely Kőrössy
    Gergely Kőrössy over 8 years
    @Arubu I created a workaround that makes it work on API 7+ too while keeps the material styles on API 14+ devices. Posted the fix here and also updated the sample project so you can test it on those devices. I only had the chance to test it in API 10 emulator.
  • Arubu
    Arubu over 8 years
    @GergelyKőrössy Great...I will test your solution. When I get a result, give you a feedback. Sorry for the delay, i did not receive email notification by your answer. Thanks
  • Arubu
    Arubu over 8 years
    @GergelyKőrössy The workaround worked like a charm. Good job. Thanks for sharing. The listview divider is not been showed, my fragment background is black color. Have you any tip?
  • Gergely Kőrössy
    Gergely Kőrössy over 8 years
    @Arubu The divider is not part of the implementation because of the generic nature of the RecyclerView, however, it can be implemented using ItemDecoration (which is not ideal and eats CPU/GPU). Regarding the black background: do you use an AppCompat Light theme as your main theme? If not, that could lead to this problem.
  • Arubu
    Arubu over 8 years
    @GergelyKőrössy No, i use Theme.AppCompat.NoActionBar as my main theme, but I tried to use AppCompat Light, no success.
  • Gergely Kőrössy
    Gergely Kőrössy over 8 years
    @Arubu Do you see this on all API levels or just below 14? In the emulator, the background is white everywhere (API 10, 16, 22), at least in my sample project.
  • Arubu
    Arubu over 8 years
    Sorry for my delay answer again. The listview divider doesn't show in everywhere. In the moment, I working in another project, but will test soon as possible again. Thanks for now
  • Gergely Kőrössy
    Gergely Kőrössy over 8 years
    @Arubu If you're still interested in the dividers, I implemented this feature now. Check out the issue.
  • jk2K
    jk2K over 8 years
    <item name="android:textColor">@color/accent_selector</item> change to <item name="android:textColor">@color/colorAccent</item> maybe better
  • Gergely Kőrössy
    Gergely Kőrössy over 8 years
    @jk2K what do you mean?
  • jk2K
    jk2K over 8 years
    @Gergely Kőrössy, For the v7, accent_selector.xml is redundant, you can use colorAccent defined in styles.xml, <item name="android:colorAccent">@color/accent</item> reference
  • Gergely Kőrössy
    Gergely Kőrössy over 8 years
    @jk2K Well, looks like it's working now. I tried with a single color earlier and it gave a runtime error that said it required a color state list, not just a single color. Probably they updated the preference category's attribute processing. Thanks.
  • Lumii
    Lumii over 8 years
    @Gergely Kőrössy Thanks. I look at your v14/styles.xml, I realize you are using android:fontFamily. Isn't android:fontFamily requires API 16?
  • Lumii
    Lumii over 8 years
    @Gergely Kőrössy : I can understand why do u need preference_fallback_accent_color in colors.xml . However, what if my app contains 2 themes which user can switch during runtime? We need to have different preference_fallback_accent_color value when the app is in different theme. May I know is it possible to achieve such?
  • Gergely Kőrössy
    Gergely Kőrössy over 8 years
    @CheokYanCheng Yes, it is available from API 16, but it doesn't matter as it will just ignore that attribute on 14-15. Haven't tried it yet on those devices though.
  • Gergely Kőrössy
    Gergely Kőrössy over 8 years
    @CheokYanCheng It is possible, added the fix to the project's repo.
  • headsvk
    headsvk over 8 years
    You should also mention that the PreferenceFragmentCompat crashes if rotated with an open dialog. code.google.com/p/android/issues/detail?id=186160
  • Gergely Kőrössy
    Gergely Kőrössy over 8 years
    It's a known issue and will be fixed in the next release, and there's nothing one can do about it right now, that's why I didn't mention it.
  • androfan
    androfan over 8 years
    @GergelyKőrössy, how can I override the android:textAppearanceLarge (titles) and android:textAppearanceSmall (summaries)? Could you give some example? When I try to do something like that: ` <style name="MyPreferenceStyle" parent="PreferenceThemeOverlay.v14"> <item name="android:textAppearanceLarge">16sp</item> </style>` I get an error.
  • Gergely Kőrössy
    Gergely Kőrössy over 8 years
    @androfan The problem with your code is that android:textAppearanceLarge is expecting a TextAppearance "object", not just a single size value. See the Styles and Themes guide for more info.
  • Edward van Raak
    Edward van Raak over 8 years
    This is ridiculous. It would take me less time to make a preference fragment from scratch than to find a way through all the bugs, workarounds and testing required to make this work 100% on all versions.
  • Gergely Kőrössy
    Gergely Kőrössy about 8 years
    Would you be interested in a version where the Fix ending is not needed in the preferences XML?
  • headsvk
    headsvk about 8 years
    Does your switch preference compat looks like shit with the latest library?
  • Gergely Kőrössy
    Gergely Kőrössy about 8 years
    @headsvk What do you mean? It looks the same.
  • headsvk
    headsvk about 8 years
    @GergelyKőrössy it started to look like this for me, looked fine few weeks ago. Does SwitchPreference look the same as SwitchPreferenceCompat below L? It is holo styled for me but everything else looks material.
  • Gergely Kőrössy
    Gergely Kőrössy about 8 years
    @headsvk Submit an issue here with screenshots and the device / version of Android you're using. It looks fine on 5.0 for me.
  • headsvk
    headsvk about 8 years
    @GergelyKőrössy I investigated the issue and it seems like I only get that with debug config / instant run, release looks fine, weird
  • kaay
    kaay about 8 years
    So much effort put into debugging... Seriously, it's broken, much better to make your own. Google failed.
  • iYonatan
    iYonatan over 7 years
    android:inputType="number" doesn't work with EditTextPreference. It shows me the normal keyboard. Am I the only one who it does not work?
  • Gergely Kőrössy
    Gergely Kőrössy over 7 years
    @iYonatan It should work unless you use the fully qualified name of EditTextPreference. What's in your XML?
  • Gergely Kőrössy
    Gergely Kőrössy over 7 years
    @iYonatan Does it work if you change inputType to phone?
  • iYonatan
    iYonatan over 7 years
    @GergelyKőrössy Nope. It still shows me the normal keyboard
  • Gergely Kőrössy
    Gergely Kőrössy over 7 years
    @iYonatan You're probably using the PreferenceFragmentCompat from the original package. Make sure it's from com.takisoft.fix.support.v7.preference.
  • iYonatan
    iYonatan over 7 years
    @GergelyKőrössy You're completely right. I didn't notice. Thanks!!
  • Louis CAD
    Louis CAD about 7 years
    This is the simplest, working solution, that requires no additional dependency. Should be the accepted answer IMHO, now that most apps are min API 14+
  • Youness
    Youness almost 7 years
    Make sure you are adding preferenceTheme to the right style which is set as theme for your activity stackoverflow.com/a/40736138/1572286
  • Jack Meister
    Jack Meister over 6 years
    The only problem with this answer is that the preference fragment will use the material theme on systems running KitKat and below. Setting preferenceTheme to PreferenceThemeOverlay.v14 in styles.xml and to PreferenceThemeOverlay.v14.Material in styles-v21.xml fixes the problem.
  • Jelmer Brands
    Jelmer Brands over 6 years
    @JackMeister you should only use the v14 version if you target api level 14 or higher. Theme incompatibility with older versions might not be your only problem when you use v14 with older api levels.
  • Jack Meister
    Jack Meister over 6 years
    @JelmerBrands Sure: you shouldn't use a v14 support library on systems running API levels below 14. My comment assumes a minSdkVersion between 14 and 20.
  • Denny
    Denny over 6 years
    Android studio cannot find this
  • Sofi Software LLC
    Sofi Software LLC over 6 years
    add com.android.support:preference-v14: to build.gradle
  • Vlad
    Vlad over 6 years
    This library freezes my app
  • Gergely Kőrössy
    Gergely Kőrössy over 6 years
    What do you mean it freezes your app?
  • user149408
    user149408 over 5 years
    Tested with 23.4.0, which works just as well. Using the v14-preference, not v7-preference, is the key.
  • Mark Lapasa
    Mark Lapasa over 3 years
    bruh - your answer is gold. So many out there but this one for me for androidx. thx