v7 Preference Support Library
com.android.support:preference-v7:25.1.0
v14 Preference Support Library
com.android.support:preference-v14:25.1.0
v7 Preference Support Library 例
public class SettingsActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportFragmentManager().beginTransaction()
.replace(android.R.id.content, new SettingsFragment())
.commit();
}
public static class SettingsFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.pref, rootKey);
}
}
}
Material Design 化 例
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.Setting">
<item name="android:listSeparatorTextViewStyle">@style/Preference.ListSeparator</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>
<style name="Preference.ListSeparator" parent="android:Widget.TextView">
<item name="android:minHeight">48dp</item>
<item name="android:gravity">center_vertical</item>
<item name="android:textAppearance">@style/TextAppearance.AppCompat.Body2</item>
<item name="android:textColor">?colorAccent</item>
<item name="android:maxLines">1</item>
<item name="android:paddingLeft">16dp</item>
<item name="android:paddingRight">16dp</item>
</style>
</resources>
values/styles_preference.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Preference">
<item name="android:layout">@layout/preference_material</item>
</style>
<style name="Preference.DropDown">
<item name="android:layout">@layout/preference_dropdown_material</item>
</style>
<style name="Preference.SeekBarPreference">
<item name="android:layout">@layout/preference_widget_seekbar_material</item>
<item name="adjustable">true</item>
<item name="showSeekBarValue">true</item>
</style>
<style name="PreferenceFragmentList">
<item name="android:paddingLeft">0dp</item>
<item name="android:paddingRight">0dp</item>
</style>
</resources>
values-v17/styles_preference.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="PreferenceFragmentList">
<item name="android:paddingStart">0dp</item>
<item name="android:paddingEnd">0dp</item>
</style>
</resources>
layout/preference_material.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:baselineAligned="false"
android:focusable="true"
android:gravity="center_vertical"
android:minHeight="72dp"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<FrameLayout
android:id="@+id/icon_frame"
android:layout_width="56dp"
android:layout_height="wrap_content">
<android.support.v7.internal.widget.PreferenceImageView
android:id="@android:id/icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_horizontal"/>
</FrameLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_weight="1"
android:orientation="vertical"
android:paddingBottom="20dp"
android:paddingTop="20dp">
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
android:textColor="?android:attr/textColorPrimary"
tools:text="title"/>
<TextView
android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:maxLines="4"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textColor="?android:attr/textColorSecondary"
tools:text="summary"/>
</LinearLayout>
<!-- Preference should place its actual preference widget here. -->
<LinearLayout
android:id="@android:id/widget_frame"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:gravity="center_vertical"
android:orientation="vertical"/>
</LinearLayout>
layout/preference_dropdown_material.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:focusable="true"
android:gravity="center_vertical"
android:minHeight="72dp"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<Spinner
android:id="@+id/spinner"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:visibility="invisible"/>
<FrameLayout
android:id="@+id/icon_frame"
android:layout_width="56dp"
android:layout_height="wrap_content">
<android.support.v7.internal.widget.PreferenceImageView
android:id="@android:id/icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_horizontal"/>
</FrameLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_weight="1"
android:orientation="vertical"
android:paddingBottom="20dp"
android:paddingTop="20dp">
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
android:textColor="?android:attr/textColorPrimary"
tools:text="title"/>
<TextView
android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:maxLines="4"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textColor="?android:attr/textColorSecondary"
tools:text="summary"/>
</LinearLayout>
<!-- Preference should place its actual preference widget here. -->
<LinearLayout
android:id="@android:id/widget_frame"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:gravity="center_vertical"
android:orientation="vertical"/>
</LinearLayout>
layout/preference_widget_seekbar_material.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- Layout used by SeekBarPreference for the seekbar widget style. -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
android:gravity="center_vertical"
android:minHeight="72dp"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<ImageView
android:id="@+android:id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:minWidth="@dimen/preference_icon_minWidth"/>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_weight="1"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingBottom="20dp"
android:paddingTop="20dp">
<TextView
android:id="@+android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
android:textColor="?android:attr/textColorPrimary"
tools:text="title"/>
<TextView
android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@android:id/title"
android:layout_alignStart="@android:id/title"
android:layout_below="@android:id/title"
android:layout_marginTop="2dp"
android:maxLines="4"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textColor="?android:attr/textColorSecondary"
tools:text="summary"/>
<!-- Using UnPressableLinearLayout as a workaround to disable the pressed state propagation
to the children of this container layout. Otherwise, the animated pressed state will also
play for the thumb in the AbsSeekBar in addition to the preference's ripple background.
The background of the SeekBar is also set to null to disable the ripple background -->
<android.support.v7.preference.UnPressableLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@android:id/title"
android:layout_alignStart="@android:id/title"
android:layout_below="@android:id/summary"
android:layout_marginTop="2dp"
android:clipChildren="false"
android:clipToPadding="false">
<SeekBar
android:id="@+id/seekbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@null"
android:clickable="false"
android:focusable="false"
android:paddingEnd="@dimen/preference_seekbar_padding_end"
android:paddingLeft="@dimen/preference_seekbar_padding_start"
android:paddingRight="@dimen/preference_seekbar_padding_end"
android:paddingStart="@dimen/preference_seekbar_padding_start"/>
<TextView
android:id="@+id/seekbar_value"
android:layout_width="@dimen/preference_seekbar_value_width"
android:layout_height="match_parent"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:fontFamily="sans-serif-condensed"
android:gravity="center"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"/>
</android.support.v7.preference.UnPressableLinearLayout>
</RelativeLayout>
</LinearLayout>