Android preference-v7 support library has some issues, this lib tries to fix them.
Clone or download
Latest commit 3a592ae Sep 24, 2018
Permalink
Failed to load latest commit information.
app Gradle updates; deprecated PreferenceFragmentCompatDividers; updated … Jul 18, 2018
gradle/wrapper Gradle plugin updates to 3.2.0-beta02 and 4.6 Jul 2, 2018
images README and CHANGELOG updates; some small updates Dec 1, 2017
preference-v7-colorpicker Gradle dependency updates Sep 24, 2018
preference-v7-datetimepicker Gradle dependency updates Sep 24, 2018
preference-v7-extras Make modules less dependent of preference-v7 Jul 11, 2018
preference-v7-material Gradle updates; deprecated PreferenceFragmentCompatDividers; updated … Jul 18, 2018
preference-v7-ringtone Updated to 28.0.0.0-rc01 Sep 13, 2018
preference-v7-simplemenu Gradle updates; deprecated PreferenceFragmentCompatDividers; updated … Jul 18, 2018
preference-v7 Fixed issue #175 Sep 24, 2018
.gitignore Working copy Aug 20, 2015
CHANGELOG.md Updated to 28.0.0.0 Sep 24, 2018
LICENSE Added additional multi-license info Aug 20, 2015
README.md Updated to 28.0.0.0 Sep 24, 2018
bintrayv.gradle Made bintrayv.gradle and installv.gradle available offline Sep 2, 2017
build.gradle Gradle repo update Sep 24, 2018
gradle.properties Working copy Aug 20, 2015
gradlew 🆙 Support Library 25.0.1 & Gradle 3.2 Nov 15, 2016
gradlew.bat Upgrade Support Library to 25.0.0, Gradle to 3.1 and Android Gradle P… Oct 23, 2016
installv.gradle Made bintrayv.gradle and installv.gradle available offline Sep 2, 2017
settings.gradle Support lib version update to 28.0.0-alpha1; added Theme.MaterialComp… Jun 12, 2018

README.md

Android Support library - preference v7 bugfix

BREAKING CHANGE in 26.1.0.3: The custom attribute names for extra preference types use pref_ prefix in order to avoid name collision with other libraries. See the changelog for more details.

This library is meant to fix some of the problems found in the official support preference-v7 library. Also, there are new preference types available, such as RingtonePreference, DatePickerPreference, and TimePickerPreference.

Support Library (28.0.0): Download

AndroidX (1.0.0-beta01): Download

Check out the other available AndroidX artifacts at https://bintray.com/takisoft/android)

Donation

If you would like to support me, you may donate some small amount via PayPal.

Buy me a coffee


How to use the library?

1. Add gradle dependency

First, remove the unnecessary lines of preference-v7 and preference-v14 from your gradle file as the bugfix contains both of them:

implementation 'com.android.support:preference-v7:28.0.0'
implementation 'com.android.support:preference-v14:28.0.0'

And add this single line to your gradle file:

implementation 'com.takisoft.fix:preference-v7:28.0.0.0'

Notice the versioning: the first three numbers are always the same as the latest official library while the last number is for own updates. I try to keep it up-to-date but if, for whatever reasons, I wouldn't notice the new support library versions, just issue a ticket.

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

You can use either PreferenceFragmentCompat or PreferenceFragmentCompatDividers. The former is the fixed version of the original fragment while the latter is an extended one where you can set the dividers using the divider flags. The PreferenceFragmentCompatDividers is the recommended approach as it uses the updated Material Design guidelines to create the appropriate divider config.

Option 1 - PreferenceFragmentCompat

import com.takisoft.fix.support.v7.preference.PreferenceFragmentCompat;

public class MyPreferenceFragment extends PreferenceFragmentCompat {

    @Override
    public void onCreatePreferencesFix(@Nullable Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.settings, rootKey);
	
	// additional setup
    }
}

Warning! Watch out for the correct package name when importing PreferenceFragmentCompat, it should come from com.takisoft.fix.support.v7.preference.


Option 2 - PreferenceFragmentCompatDividers

Warning! PreferenceFragmentCompatDividers is deprecated and will be removed from the AndroidX version of the lib. You should use PreferenceFragmentCompat instead.

import com.takisoft.fix.support.v7.preference.PreferenceFragmentCompatDividers;

public class MyPreferenceFragment extends PreferenceFragmentCompatDividers {

    @Override
    public void onCreatePreferencesFix(@Nullable Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.settings, rootKey);

	// additional setup
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, @Nullable Bundle savedInstanceState) {
        try {
            return super.onCreateView(inflater, container, savedInstanceState);
        } finally {
            setDividerPreferences(DIVIDER_PADDING_CHILD | DIVIDER_CATEGORY_AFTER_LAST | DIVIDER_CATEGORY_BETWEEN);
        }
    }
}

3. Use the appropriate theme

You should set your containing Activity's theme to either a variant of @style/PreferenceFixTheme or create your own and use it as the parent theme. PreferenceFixTheme is based on Theme.AppCompat and contains the required attribute preferenceTheme. The fix theme is available for all Theme.AppCompat variants, such as NoActionBar, Light, etc. For example, the sample app uses PreferenceFixTheme.Light.NoActionBar as the parent theme:

<style name="Theme.MyTheme" parent="@style/PreferenceFixTheme.Light.NoActionBar">
    <item name="colorAccent">@color/accent</item>
    <item name="colorPrimary">@color/primary</item>
    <item name="colorPrimaryDark">@color/primary_dark</item>
    <!-- [...] -->
</style>

Theme.MaterialComponents There's a NEW module called preference-v7-material that provides the new Theme.MaterialComponents related themes. You can add it to your project like this:

implementation 'com.takisoft.fix:preference-v7-material:28.0.0.0'

Note that you may need to use multidexing after this because it uses the support design library which is a huge codebase.

4. That's it!

Now you can enjoy using the support preferences API without losing all your hair.


Extra types

There are additional preferences not part of the official support library, but decided to add them to some extra libraries. You can add all of them to your project using

implementation 'com.takisoft.fix:preference-v7-extras:28.0.0.0'

or one or more groups:

Preference Dependency Preview
RingtonePreference compile 'com.takisoft.fix:preference-v7-ringtone:28.0.0.0' API 26
DatePickerPreference compile 'com.takisoft.fix:preference-v7-datetimepicker:28.0.0.0' API 26
TimePickerPreference compile 'com.takisoft.fix:preference-v7-datetimepicker:28.0.0.0' API 26
ColorPickerPreference compile 'com.takisoft.fix:preference-v7-colorpicker:28.0.0.0' API 26
SimpleMenuPreference compile 'com.takisoft.fix:preference-v7-simplemenu:28.0.0.0' API 26

Custom solutions

Dividers

If you use PreferenceFragmentCompatDividers as your base class for the preference fragment, you can use 3 new methods to customize the dividers:

  • setDivider(Drawable drawable): Sets a custom Drawable as the divider.
  • setDividerHeight(int height): Sets the height of the drawable; useful for XML resources.
  • setDividerPreferences(int flags): Sets where the dividers should appear. Check the documentation of the method for more details about the available flags.

Hijacked EditTextPreference

The support implementation of EditTextPreference ignores many of the basic yet very important attributes as it doesn't forward them to the underlying EditText widget. In my opinion this is a result of some twisted thinking which would require someone to create custom dialog layouts for some simple tasks, like showing a numbers-only dialog. This is the main reason why the EditTextPreference gets hijacked by this lib: it replaces certain aspects of the original class in order to forward all the XML attributes set (such as inputType) on the EditTextPreference to the EditText, and also provides a getEditText() method so it can be manipulated directly.

The sample app shows an example of setting (via XML) and querying (programmatically) the input type of the EditTextPreference:

<EditTextPreference
    android:inputType="phone"
    android:key="edit_text_test" />
EditTextPreference etPref = (EditTextPreference) findPreference("edit_text_test");
if (etPref != null) {
    int inputType = etPref.getEditText().getInputType();
    // do something with inputType
}

Note! Watch out for the correct package name when importing EditTextPreference, it should come from com.takisoft.fix.support.v7.preference. If you import from the wrong package (i.e. android.support.v7.preference), the getEditText() method will not be available, however, the XML attributes will still be forwarded and processed by the EditText.

PreferenceCategory's bottom margin reduce

Some people found the preference category's bottom margin too big, so now you can change it from the styles by setting the preferenceCategory_marginBottom value in your theme, for example:

<item name="preferenceCategory_marginBottom">0dp</item>

Preference dialog's message style

The original implementation uses ?attr/textAppearanceSmall as the message style in the popup dialog (the one you find when clicking on an EditTextPreference with a set android:dialogMessage attribute), but it seems really small and might be hard to read. In order to fix that, a new attribute has been introduced to the PreferenceFixTheme: preferenceDialog_messageAppearance. This attribute controls the appearance of the message in the dialog and is set to @style/TextAppearance.AppCompat.Subhead by default. If you wish to change this, you'll just have to add the following line to your theme:

<item name="preferenceDialog_messageAppearance">@style/YourTextAppearance</item>

Version

The current stable version is 28.0.0.0.

Notes

This demo / bugfix is set to work on API level 14+.


Sample

Material design - everywhere.

API 15 API 21 API 26
API 15 API 21 API 26

Changelog

2018-09-24

New version: 28.0.0.0 (based on v28.0.0)

  • No support preferences related changes in the support library.
  • Fixed issues #174 and #175

2018-09-13

New version: 28.0.0.0-rc02 (based on v28.0.0-rc02)

  • No support preferences related changes in the support library.

2018-09-13

New version: 28.0.0.0-rc01 (based on v28.0.0-rc01)

  • Official lib bug fixes
    • PreferenceThemeOverlay has been updated to the latest material theme. If no custom theme is provided, PreferenceThemeOverlay is used as the default theme.
    • PreferenceThemeOverlay.v14 and PreferenceThemeOverlay.v14.Material themes have been deprecated in favour of PreferenceThemeOverlay.
    • PreferenceGroup visibility is now tied to its children - hiding a parent group will also prevent its children from being shown in the hierarchy. Use Preference.isShown() to get whether a Preference is actually displayed to the user in the hierarchy.
    • Preference.onSetInitialValue(boolean, Object) has been deprecated and replaced with onSetInitialValue(Object). PreferenceDataStore now also correctly restores default values.
  • added onSetInitialValue(Object) implementation and removed the deprecated onSetInitialValue(boolean, Object)

2018-07-18

New version: 28.0.0.0-alpha3 (based on v28.0.0-alpha3)

  • No support preferences related changes in the support library.
  • PreferenceFragmentCompatDividers is now deprecated. Use PreferenceFragmentCompat instead.
  • Added preference-v7-material module which provides Theme.MaterialComponents related themes.
  • Bug fixes #166, #169, #173

2018-07-04

New version: 27.1.1.2 (based on v27.1.1)

  • No support preferences related changes in the support library.
  • RingtonePreference bug fixes(#164, #165, #167).

2018-05-11

New version: 27.1.1.1 (based on v27.1.1)

  • No support preferences related changes in the support library.
  • Bug fixes (#153, #149, #155, #152).

2018-04-10

New version: 27.1.1.0 (based on v27.1.1)

  • No support preferences related changes in the support library.
  • Some bug fixes (see #147 for more info).

For older changelogs, check out the CHANGELOG file.

Feel free to ask / suggest anything on this page by creating a ticket (issues)!

License notes

You can do whatever you want except where noted.