PreferenceFragmentCompat requires preferenceTheme to be set
I

13

115

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

Impediment answered 18/8, 2015 at 11:5 Comment(3)
There is a bug about the documentation for this here: code.google.com/p/android/issues/…Impediment
Personally I don't think that these solutions are worth the workarounds. Try github.com/kolavar/android-support-v4-preferencefragmentEnce
Can you please mark https://mcmap.net/q/153590/-preferencefragmentcompat-requires-preferencetheme-to-be-set as the accepted answer?Intervene
C
159

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.

Cherriecherrita answered 20/8, 2015 at 2:3 Comment(58)
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?Ahmad
This produces the same result as just using Bogato's answer of setting <item name="preferenceTheme">@style/PreferenceThemeOverlay</item> directly in the theme. As @Ahmad says, the styles are incorrect.Impediment
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...Ordinal
@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.Impediment
I might try to put the material design in place for pre-21 devices as well, they look the same as the original now.Ordinal
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?Orna
Do you instantiate the old Preference class or the support one?Ordinal
@GergelyKőrössy I used the new android.support.v7.preferences.PreferenceOrna
@GergelyKőrössy I posted my own question, can you give it a look please?Orna
The project Android-Support-Preference-V7-Fix has minSdkVersion: 16 I suppose it doesn't work on API level 10...Audition
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.Ordinal
When dependency 'com.android.support:preference-v14:23.0.1' is added, the manifest merger complains that minSdkVersion must be at least 14...Audition
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...Ordinal
@GergelyKőrössy do you have an idea why there are no divider lines between the preference items?Spawn
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.Ordinal
Thanks for providing a GitHub project to demonstrate the solution. It is very much useful to have a minimal workable example as solution.Amplify
Btw, is there any way we can make this works, for API 10 and above?Amplify
@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.Ordinal
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.Amplify
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.Ordinal
@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.Pummel
@Pummel 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.Ordinal
@Pummel 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.Ordinal
@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. ThanksPummel
@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?Pummel
@Pummel 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.Ordinal
@GergelyKőrössy No, i use Theme.AppCompat.NoActionBar as my main theme, but I tried to use AppCompat Light, no success.Pummel
@Pummel 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.Ordinal
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 nowPummel
@Pummel If you're still interested in the dividers, I implemented this feature now. Check out the issue.Ordinal
<item name="android:textColor">@color/accent_selector</item> change to <item name="android:textColor">@color/colorAccent</item> maybe betterWillianwillie
@Willianwillie what do you mean?Ordinal
@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> referenceWillianwillie
@Willianwillie 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.Ordinal
@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?Amplify
@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?Amplify
@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.Ordinal
@CheokYanCheng It is possible, added the fix to the project's repo.Ordinal
You should also mention that the PreferenceFragmentCompat crashes if rotated with an open dialog. code.google.com/p/android/issues/detail?id=186160Punctilious
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.Ordinal
@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.Prosecutor
@Prosecutor 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.Ordinal
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.Aubrette
Would you be interested in a version where the Fix ending is not needed in the preferences XML?Ordinal
Does your switch preference compat looks like shit with the latest library?Punctilious
@Punctilious What do you mean? It looks the same.Ordinal
@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.Punctilious
@Punctilious Submit an issue here with screenshots and the device / version of Android you're using. It looks fine on 5.0 for me.Ordinal
@GergelyKőrössy I investigated the issue and it seems like I only get that with debug config / instant run, release looks fine, weirdPunctilious
So much effort put into debugging... Seriously, it's broken, much better to make your own. Google failed.Trogon
android:inputType="number" doesn't work with EditTextPreference. It shows me the normal keyboard. Am I the only one who it does not work?Eliason
@Eliason It should work unless you use the fully qualified name of EditTextPreference. What's in your XML?Ordinal
@Eliason Does it work if you change inputType to phone?Ordinal
@GergelyKőrössy Nope. It still shows me the normal keyboardEliason
@Eliason You're probably using the PreferenceFragmentCompat from the original package. Make sure it's from com.takisoft.fix.support.v7.preference.Ordinal
@GergelyKőrössy You're completely right. I didn't notice. Thanks!!Eliason
This library freezes my appVestry
What do you mean it freezes your app?Ordinal
B
46

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.

Beanfeast answered 18/8, 2015 at 13:10 Comment(5)
This works, but it looks wrong. The fonts of the preference elements are too big (tested on android 4.1 and 5.1).Fleeman
@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.Impediment
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=183376Impediment
How do I make the theme look material-design? Currently it shows the native look for me...Vhf
Read my answer below.Ordinal
A
35

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"
Androsphinx answered 29/5, 2017 at 7:7 Comment(4)
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.Butterfield
@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.Genethlialogy
@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.Butterfield
Tested with 23.4.0, which works just as well. Using the v14-preference, not v7-preference, is the key.Endodontics
L
14

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.

Lillalillard answered 1/9, 2015 at 6:52 Comment(1)
Make sure you are adding preferenceTheme to the right style which is set as theme for your activity https://mcmap.net/q/153593/-java-lang-illegalstateexception-must-specify-preferencetheme-in-themeMyocardium
B
14

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

<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
Belong answered 22/1, 2017 at 3:54 Comment(3)
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+Cellar
Android studio cannot find thisRouvin
add com.android.support:preference-v14: to build.gradleHaftarah
W
4

Add this code to your styles.xml and modify it according. It should work fine.

<!-- 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>

Wandie answered 2/4, 2017 at 9:27 Comment(1)
bruh - your answer is gold. So many out there but this one for me for androidx. thxPlummy
F
3

Solution that worked for me in API 25. I had this default theme:

<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>

And added this line to it

<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 was was already defined, I didn't have to include it. It worked on Android 4.x and 5.x devices of my own

Favorite answered 31/3, 2017 at 12:9 Comment(0)
F
1

I added the "preferenceTheme" item into my style and that seemed to fix the issue:

   <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>
Firearm answered 19/8, 2015 at 4:39 Comment(0)
K
1

The most helpful site for me: Medium

Author shows that we need to add two packages: com.android.support:preference-v7 and com.android.support:preference-v14, because the first one it being distributed without styles.

Let me know if it works

Koa answered 6/10, 2017 at 6:39 Comment(0)
E
0

The accepted "Takisoft Fix" seems rather kludgy and after playing around with it, I am still not satisfied with the resulting look.

If you need API 9+ PreferenceFragment support library, I recommend using Material Preference Support Library. It works perfectly (at least for me).

Eadwine answered 24/2, 2017 at 10:1 Comment(0)
M
0

The problem occurs because the AAPT(Android Asset Packaging Tool) cannot find some resources. Fix this issue as follows:

1.Copy resources which are necessary to a new responding resource folder, named like res_fw_v7_preference or something else.

2.Using gradle to build your application and add some additional AAPT options in build.gradle(module's) like this:

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:!*~'
    }
    ...
}

Hope this is helpful:)

Mccowan answered 9/5, 2017 at 12:41 Comment(0)
C
0

Thanks @sergio for answer, using <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item> instead of <item name="preferenceTheme">@style/Preference</item> works great for me.

<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>
Cabalist answered 4/3, 2018 at 6:29 Comment(0)
L
-8

Just let it go and use API 11+.

API 7 is almost seven years old now.

Laniary answered 16/7, 2016 at 23:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.