Material theme for preference widgets.
Backporting dat material look and functionality.
Available from API 7. Depends on preference-v7.
dependencies {
compile 'net.xpece.android:support-preference:0.5.9' // depends on preference-v7 r23.2.1
/* or */
compile 'net.xpece.android:support-preference:0.5.4' // depends on preference-v7 r23.1.1
}
Library version 0.5.9. Android version 4.4.
Showcasing Simple Menus and custom title and summary text appearance.
Library version 0.5.1. Android version 4.4.
Preference
CheckBoxPreference
SwitchPreference
- Using
SwitchCompat
available from API 7
- Using
DialogPreference
- Uses AppCompat AlertDialog Material theme
EditTextPreference
ListPreference
- Optionally can display as a simple menu.
MultiSelectListPreference
- Available since API 7
SeekBarDialogPreference
extendsDialogPreference
- Made public
SeekBarPreference
- Made public
- According to http://www.google.com/design/spec/components/dialogs.html#dialogs-confirmation-dialogs
RingtonePreference
- Coerced Ringtone Picker Activity from AOSP
XpPreferenceFragment
- Handles proper Preference inflation and DialogPreference dialogs
SharedPreferencesCompat
getStringSet
andputStringSet
methods allow persisting string sets even before API 11
- Material preference item layouts out of the box.
- Icon and dialog icon tinting and padding.
EditTextPreference
understandsEditText
XML attributes.- Several preference widgets not publicly available in preference-v7 or SDK.
RingtonePreference
,SeekBarPreference
,SeekBarDialogPreference
,MultiSelectListPreference
- Subscreen navigation implementation.
ListPreference
can optionally show as a Simple Menu in a popup instead of a dialog.
Your preference fragment needs to extend XpPreferenceFragment
.
Setup your preference items in the following method:
public void onCreatePreferences2(final Bundle savedInstanceState, final String rootKey) {
// ...
}
Your settings activity theme needs to specify the following values:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Used to theme preference list and items. -->
<item name="preferenceTheme">@style/PreferenceThemeOverlay.Material</item>
<!-- Default preference icon tint color. -->
<item name="preferenceTint">@color/accent_state_list</item>
</style>
Styling alertDialogTheme
is recommended for a proper color theme. See the sample project.
Sample res/color/accent_state_list.xml
:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:color="@color/accent_disabled"
android:state_enabled="false"/>
<item android:color="@color/accent"/>
</selector>
Disabled alpha is 38% (#61) according to latest Material design guidelines.
Preference-v7 r23.2.0 provides a divider implementation out of the box.
If you want to customize how this divider looks you can call setDivider(...)
and setDividerHeight(...)
.
Preference-v7 divider will be drawn just between items and at the bottom of the list. It will not be drawn before the end of category.
If you want more control over where the dividers are drawn, disable the default implementation and use my own instead:
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getListView().addItemDecoration(new PreferenceDividerDecoration(getContext()).drawBottom(true));
setDivider(null);
}
Preference-v7 r23.1.1 does not provide a default divider so you don't need to call setDivider(null)
.
RingtonePicker
will show only system ringtones/notification sounds by default.
If you want to include sounds from the external storage your app needs to request
android.permission.READ_EXTERNAL_STORAGE
permission in its manifest.
Don't forget to check this runtime permission before opening ringtone picker on API 23.
As PreferenceScreen
class is final and hardwired into preference system
I was unable to automate icon tinting and padding. However you are able to do this yourself:
Preference subs = findPreference("subs_screen");
PreferenceIconHelper subsHelper = new PreferenceIconHelper(subs);
subsHelper.setIconPaddingEnabled(true); // Call this BEFORE setIcon!
subsHelper.setIcon(R.drawable.some_icon);
subsHelper.setTintList(ContextCompat.getColorStateList(getPreferenceManager().getContext(), R.color.accent));
subsHelper.setIconTintEnabled(true);
One solution is implemented in PreferenceScreenNavigationStrategy.ReplaceRoot
class.
Please review the sample project for an example solution.
Simple menu is described in Material Design specs.
If you want to show your ListPreference
in a popup instead of a dialog use this configuration:
<ListPreference
style="@style/Preference.Material.DialogPreference.ListPreference.SimpleMenu"/>
The width of the popup window will try to accommodate all items and be a multiple of 56dp on phones and 64dp on tablets.
You can specify app:asp_simpleMenuWidthUnit
attribute to override this behavior:
match_parent
orwrap_content
: Same width as underlyingListPreference
view.0dp
: Popup wraps its own content (max width being limited by the width of underlyingListPreference
).Xdp
: Popup wraps its own content and expands to the nearest multiple of X (being limited by the width of underlyingListPreference
).
In appcompat-v7 r23.1.1 library there is a bug which prevents tinting of checkmarks in lists.
Call Fixes.updateLayoutInflaterFactory(getLayoutInflater())
right after
super.onCreate(savedInstanceState)
in your Activity.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Fixes.updateLayoutInflaterFactory(getLayoutInflater());
setContentView(R.layout.activity_settings);
//...
}
This fix is not necessary or available since version 0.5.5.
-
app:asp_tint
-
app:asp_tintMode
-
app:asp_tintEnabled
-
app:asp_iconPaddingEnabled
-
app:asp_dialogTint
-
app:asp_dialogTintMode
-
app:asp_dialogTintEnabled
-
app:asp_dialogIconPaddingEnabled
-
app:asp_simpleMenu
-
app:asp_simpleMenuWidthUnit
Application icons (48dp x 48dp) require no extra padding.
For smaller icons extra padding of 4dp on each side is needed.
Achieve this by using app:asp_iconPaddingEnabled
and app:asp_dialogIconPaddingEnabled
attributes. Icon padding is enabled by default.
Since version 0.5.1 Proguard rules are bundled with the library.
0.5.9
- FIXED: Simple menu.
- Showing simple menu is restored after screen orientation change.
- Aligning simple menu width to 56dp/64dp grid on phones/tablets (customizable).
0.5.8
- FIXED: Simple menu.
- Preselected option is now highlighted.
- Fixed animation on Android 4 - fading in.
- Fixed popup width on Android 4.
- Two line items now have top and bottom padding.
0.5.6 Deprecated
- NEW! Custom title and summary text styles.
app:titleTextAppearance
andapp:titleTextColor
for titles.app:subtitleTextAppearance
andapp:subtitleTextColor
for summaries.- Analogous methods available in Java.
- FIXED: Simple menu.
- Popup window adjusts its width according to its own content.
- Added top and bottom padding to popup window.
- Items can have up to two lines of text (increased form one).
- Added persistent scrollbar if all items don't fit on screen.
0.5.5 Deprecated
- Only supports appcompat-v7 with preference-v7 version 23.2.0!
0.5.4
- NEW! Simple menu variant of
ListPreference
.- Via
app:asp_simpleMenu="true"
. - Described here https://www.google.com/design/spec/components/menus.html#menus-simple-menus
- Does not have top and bottom padding yet.
- Menu position is unpredictable when having more than 3 menu items and the preference is first or last in the list.
- To be updated later.
- Via
- FIXED: Small icon is properly aligned in RTL configurations.
0.5.3 Deprecated
- FIXED: Ringtone picker does not need
READ_EXTERNAL_STORAGE
permission even prior to Android 6.
0.5.2 Deprecated
- FIXED:
PreferenceScreenNavigationStrategy.ReplaceRoot
no longer crashes on screen rotation. - FIXED: Ringtone picker does not stop playback on screen rotation.
0.5.1 Deprecated
- NEW!
PreferenceScreenNavigationStrategy
class. - FIXED: Missing Proguard rules are now bundled with the library.
- FIXED: Incorrect icon size on Lollipop.
0.5.0 Deprecated
- Only supports appcompat-v7 with preference-v7 version 23.1.1!
- NEW! Based on preference-v7 instead of native preferences.
- Updated appcompat-v7 library to 23.1.1.
- Material SeekBar style across all platforms.
RingtonePreference
is nowDialogFragment
based.- Unmanaged preference icons (such as that of
PreferenceScreen
) can be tinted viaPreferenceIconHelper
. - Default preference icon tint specified by
preferenceTint
theme attribute. - Fixed divider color.
- Sample contains
PreferenceScreen
subscreen handling.
0.4.3
- Last fully supported appcompat-v7 version is 23.0.1. After that ringtone picker crashes!
- No more
Resources.NotFoundException
inRingtonePickerActivity
. Falls back to English. - Updated appcompat-v7 library to 22.2.1.
0.4.2 Deprecated
SeekBar
tinting can be turned off viaapp:asp_tintSeekBar="false"
- Introduced missing
seekBarDialogPreference
style
0.4.1 Deprecated
- Ringtone picker strings are now taken dynamically from
android
andcom.android.providers.media
packages, falls back to EnglishThese are accessible viaRingtonePickerActivity.get*String(Context)
0.4.0 Deprecated
- NEW! Implemented SeekBarPreference according to http://www.google.com/design/spec/components/dialogs.html#dialogs-confirmation-dialogs
- FIXED: tinting/padding in DialogPreference and SeekBarDialogPreference
AppCompatPreferenceActivity and PreferenceFragment now implement Factory- NEW! app:asp_dialogIconPaddingEnabled attribute
0.3.0 Deprecated
- Removed
MultiCheckPreference
as it was only partially implemented andMultiSelectListPreference
provides the same function. MultiSelectListPreference
is now available since API 7 (formerly API 11). UsesJSONArray
to persistSet<String>
.- API for persisting and accessing string sets since API 7 is available via
SharedPreferencesCompat
. Preference
s now supportapp:asp_iconPaddingEnabled
attribute which allows to better align non-launcher icons to 16dp keyline.Custom preferences are now recycled which fixed animation issues on Lollipop.- Custom preferences are now always inflated on all platforms if using
AppCompatPreferenceActivity
and/or customPreferenceFragment
. - Library no longer includes
android.permission.READ_EXTERNAL_STORAGE
permission (used to read ringtones). You have to do it yourself.- This is needed because the custom picker is part of the app and not provided by system.
You are of course free to useandroid.preference.RingtonePreference
when necessary.
0.2.2 Deprecated
- optional tinting
via.app:asp_tintIcon="true"
andapp:asp_tintDialogIcon="true"
andasp_tint
andasp_tintMode
0.2.1 Deprecated
- No need for
net.xpece.android.support.preference.
prefix in XML files defining preferences, framework will choose automatically:On Lollipop nativePreference
,CheckBoxPreference
,SwitchPreference
will be used.Otherwise support version will be used.Force either version by using fully qualified class name.You need to useAppCompatPreferenceActivity
or specialPreferenceFragment
both of which are provided.
AddedPreferenceCompat#setChecked(Preference, boolean)
helper method.
0.1.2 Deprecated
- Czech strings
SeekBar
inSeekBarDialogActivity
usesColorFilter
to match theme
0.1.1 Deprecated
- Initial release
- Backported material style and icon capability for
Preference
children - Backported
SwitchPreference
- Material styled
RingtonePreference
picker dialog/activity
- SwitchPreference does not animate its SwitchCompat widget when clicked.
- MultiSelectListPreference items may be incorrectly tinted on Android 2.
- SeekBarPreference's SeekBar may appear in disabled state until clicked on Android 2.
- Why are some of your classes in
android.support.v7
packages?- I'm using their package private features to achieve consistent results.
Most of this library is straight up pillaged latest SDK mixed with heavy reliance on appcompat-v7. Since version 0.5.0 the same applies to preference-v7. Kudos to people who create and maintain these!