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.
Check out the other available AndroidX artifacts at https://bintray.com/takisoft/android)
If you would like to support me, you may donate some small amount via PayPal.
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.
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.
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 fromcom.takisoft.fix.support.v7.preference.
Warning!
PreferenceFragmentCompatDividersis deprecated and will be removed from the AndroidX version of the lib. You should usePreferenceFragmentCompatinstead.
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);
}
}
}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.
Now you can enjoy using the support preferences API without losing all your hair.
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' |
![]() |
DatePickerPreference |
compile 'com.takisoft.fix:preference-v7-datetimepicker:28.0.0.0' |
![]() |
TimePickerPreference |
compile 'com.takisoft.fix:preference-v7-datetimepicker:28.0.0.0' |
![]() |
ColorPickerPreference |
compile 'com.takisoft.fix:preference-v7-colorpicker:28.0.0.0' |
![]() |
SimpleMenuPreference |
compile 'com.takisoft.fix:preference-v7-simplemenu:28.0.0.0' |
![]() |
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 customDrawableas 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.
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 fromcom.takisoft.fix.support.v7.preference. If you import from the wrong package (i.e.android.support.v7.preference), thegetEditText()method will not be available, however, the XML attributes will still be forwarded and processed by theEditText.
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>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>The current stable version is 28.0.0.0.
This demo / bugfix is set to work on API level 14+.
Material design - everywhere.
| API 15 | API 21 | API 26 |
|---|---|---|
![]() |
![]() |
![]() |
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
PreferenceThemeOverlayhas been updated to the latest material theme. If no custom theme is provided,PreferenceThemeOverlayis used as the default theme.PreferenceThemeOverlay.v14andPreferenceThemeOverlay.v14.Materialthemes have been deprecated in favour ofPreferenceThemeOverlay.PreferenceGroupvisibility is now tied to its children - hiding a parent group will also prevent its children from being shown in the hierarchy. UsePreference.isShown()to get whether aPreferenceis actually displayed to the user in the hierarchy.Preference.onSetInitialValue(boolean, Object)has been deprecated and replaced withonSetInitialValue(Object). PreferenceDataStore now also correctly restores default values.
- added
onSetInitialValue(Object)implementation and removed the deprecatedonSetInitialValue(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.
PreferenceFragmentCompatDividersis now deprecated. UsePreferenceFragmentCompatinstead.- Added
preference-v7-materialmodule which providesTheme.MaterialComponentsrelated 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)!
You can do whatever you want except where noted.








