PreferenceFragmentCompat requires preferenceTheme to be set
Solution 1
The bugfix is available as a gradle dependency
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>
Related videos on Youtube
![Igoussam](https://lh3.googleusercontent.com/--92UsP4VgA4/AAAAAAAAAAI/AAAAAAAAAD8/HQ4_u8PVNIg/photo.jpg?sz=256)
Comments
-
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:
Native preferences:
-
Igoussam almost 9 yearsThere is a bug about the documentation for this here: code.google.com/p/android/issues/…
-
MidasLefko over 8 yearsPersonally I don't think that these solutions are worth the workarounds. Try github.com/kolavar/android-support-v4-preferencefragment
-
Sam over 6 yearsCan you please mark stackoverflow.com/a/44236460/238753 as the accepted answer?
-
-
Admin almost 9 yearsThis works, but it looks wrong. The fonts of the preference elements are too big (tested on android 4.1 and 5.1).
-
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 almost 9 yearsThe 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 almost 9 yearsThis 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 almost 9 yearsI'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 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 almost 9 yearsI might try to put the material design in place for pre-21 devices as well, they look the same as the original now.
-
Igoussam almost 9 yearsI 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 almost 9 yearsHow do I make the theme look material-design? Currently it shows the native look for me...
-
Gergely Kőrössy almost 9 yearsRead my answer below.
-
Spotlight almost 9 yearsHi, 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 almost 9 yearsDo you instantiate the old Preference class or the support one?
-
Spotlight almost 9 years@GergelyKőrössy I used the new
android.support.v7.preferences.Preference
-
Spotlight almost 9 years@GergelyKőrössy I posted my own question, can you give it a look please?
-
petrsyn almost 9 yearsThe project Android-Support-Preference-V7-Fix has minSdkVersion: 16 I suppose it doesn't work on API level 10...
-
Gergely Kőrössy almost 9 yearsYou 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 almost 9 yearsWhen 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 almost 9 yearsWell, 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 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 almost 9 yearsIt'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 over 8 yearsThanks for providing a GitHub project to demonstrate the solution. It is very much useful to have a minimal workable example as solution.
-
Lumii over 8 yearsBtw, is there any way we can make this works, for API 10 and above?
-
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 over 8 yearsIn 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 over 8 yearsYeah, 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 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 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 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 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 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 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 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 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 over 8 yearsSorry 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 over 8 years@Arubu If you're still interested in the dividers, I implemented this feature now. Check out the issue.
-
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 over 8 years@jk2K what do you mean?
-
jk2K over 8 years@Gergely Kőrössy, For the v7,
accent_selector.xml
is redundant, you can usecolorAccent
defined instyles.xml
,<item name="android:colorAccent">@color/accent</item>
reference -
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 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 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 differentpreference_fallback_accent_color
value when the app is in different theme. May I know is it possible to achieve such? -
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 over 8 years@CheokYanCheng It is possible, added the fix to the project's repo.
-
headsvk over 8 yearsYou 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 over 8 yearsIt'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 over 8 years@GergelyKőrössy, how can I override the
android:textAppearanceLarge
(titles) andandroid: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 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 over 8 yearsThis 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 about 8 yearsWould you be interested in a version where the
Fix
ending is not needed in the preferences XML? -
headsvk about 8 yearsDoes your switch preference compat looks like shit with the latest library?
-
Gergely Kőrössy about 8 years@headsvk What do you mean? It looks the same.
-
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 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 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 about 8 yearsSo much effort put into debugging... Seriously, it's broken, much better to make your own. Google failed.
-
iYonatan over 7 yearsandroid: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 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 over 7 years@iYonatan Does it work if you change
inputType
to phone? -
iYonatan over 7 years@GergelyKőrössy Nope. It still shows me the normal keyboard
-
Gergely Kőrössy over 7 years@iYonatan You're probably using the
PreferenceFragmentCompat
from the original package. Make sure it's fromcom.takisoft.fix.support.v7.preference
. -
iYonatan over 7 years@GergelyKőrössy You're completely right. I didn't notice. Thanks!!
-
Louis CAD about 7 yearsThis 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 almost 7 yearsMake sure you are adding preferenceTheme to the right style which is set as theme for your activity stackoverflow.com/a/40736138/1572286
-
Jack Meister over 6 yearsThe only problem with this answer is that the preference fragment will use the material theme on systems running KitKat and below. Setting
preferenceTheme
toPreferenceThemeOverlay.v14
instyles.xml
and toPreferenceThemeOverlay.v14.Material
instyles-v21.xml
fixes the problem. -
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 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 over 6 yearsAndroid studio cannot find this
-
Sofi Software LLC over 6 yearsadd com.android.support:preference-v14: to build.gradle
-
Vlad over 6 yearsThis library freezes my app
-
Gergely Kőrössy over 6 yearsWhat do you mean it freezes your app?
-
user149408 over 5 yearsTested with 23.4.0, which works just as well. Using the v14-preference, not v7-preference, is the key.
-
Mark Lapasa over 3 yearsbruh - your answer is gold. So many out there but this one for me for androidx. thx