2017年1月10日火曜日

v7 Preference Support Library を Material Design にする

フレームワーク

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>