创建 Android 设置界面 (第一部分)

1-8dPldA5KlCFUX4u71G89lQ.png

几天前,我开始为我的Android app做设置界面。要不是在老设备上打开来看,我还以为一切正常呢。如果仅仅是界面不符合material design倒是可以接受,问题是对话框完全毁了:Android的 internal preferences 使用Android的 internal app.AlertDialog,这些dialog和AppCompat Dialog 结合导致在旧设备上的对话框有两个框 (一个系统默认的dialog 以及一个 material 边框 )。所以我决定使用android.support.v7.preference library,谁知道遇到更多问题。

这个系列教程帮助你学习如何修复v7.preference library的几个问题以及如何创建自定义的preference。

引入库

要使用新的preferences,我们需要引入一个library,为此,在 gradle dependencies 中添加这行代码(记得把版本号换成最新的)。

compile 'com.android.support:preference-v7:23.4.0'

创建 Preference Screen

创建 Preference

首先,我们得创建preference的结构:创建新的XML资源文件 xml/app_preferences.xml。然后在这个文件中添加preference结构。记住保证每个preference的 android:key 属性的唯一性。更多信息请看:如何构建 XML

<android.support.v7.preference.PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android">
    <android.support.v7.preference.PreferenceCategory
        android:title="Category 1">
        <android.support.v7.preference.SwitchPreferenceCompat
            android:key="key1"
            android:title="Switch Preference"
            android:summary="Switch Summary"
            android:defaultValue="true" />
        <android.support.v7.preference.EditTextPreference
            android:key="key2"
            android:title="EditText Preference"
            android:summary="EditText Summary"
            android:dialogMessage="Dialog Message"
            android:defaultValue="Default value" />
        <android.support.v7.preference.CheckBoxPreference
            android:key="key3"
            android:title="CheckBox Preference"
            android:summary="CheckBox Summary"
            android:defaultValue="true"/>
    </android.support.v7.preference.PreferenceCategory>
</android.support.v7.preference.PreferenceScreen>

 v7.preference library提供了几种预定义的preferences:CheckBoxPreference, SwitchPreferenceCompat, EditTextPreference 以及 ListPreference (以及一个基本的 Preference)。如果你想要的preference在此之外,就得自定义了。

创建 Preference Fragment

现在我们需要创建Preference Fragment来显示XML文件中的preference了。创建一个继承PreferenceFragmentCompat的类,名为SettingsFragment。因为onCreatePreferences方法是一个抽象方法,我们必须重写它并在其中加载刚刚创建的app_preferences.xml。

import android.support.v7.preference.PreferenceFragmentCompat;
public class SettingsFragment extends PreferenceFragmentCompat {
    @Override
    public void onCreatePreferences(Bundle bundle, String s) {
        // Load the Preferences from the XML file
        addPreferencesFromResource(R.xml.app_preferences);
    }
}

像普通的Fragment一样,我们可以使用FragmentTransaction把这个SettingsFragment添加到任意Activity中。

应用 Preference 主题

最后我们需要为Activity指定一个preference主题。如果不这样app就会崩溃。v7.preference library 只提供了一个主题: PreferenceThemeOverlay (你可以看看它的 源代码)。在 Activity的theme中,我们用下面这行代码来添加这个主题: 

<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>

完了之后,效果应该是这样的。
( Activity 的 parent theme 是 Theme.AppCompat , background 设置为 android:windowBackground)

1-x4jeIKbHKopwJCV7Q8zP1w.png

就如你看到的,里面存在大一号的字体,在分类标题下面有一条横线,这可不是material design的。

它看上去更像 material design 的 CheckBox和开关控件与老式设计的混合体。

于是我们开始下个话题:在setting上应用material主题。

应用 Material Design 主题

既然在当前的preference library中没有material主题,我们就需要引入 v14.preference library 了。奇怪的是谷歌为什么要把这两个library分开,因为 v14 版本显然只是 v7.preference library的增量。不管如何,这对于我们而言就是需要再添加一个依赖。

compile 'com.android.support:preference-v14:23.4.0'

现在我们就多了两个主题:PreferenceThemeOverlay.v14 以及 PreferenceThemeOverlay.v14.Material (你可以看看它们的源代码)。要使用material主题,我们只需修改Activity主题中的preferenceTheme。

<item name="preferenceTheme">
    @style/PreferenceThemeOverlay.v14.Material
</item>

引入v14.preference library 的一个额外收获是我们可以使用一个名为MultiSelectListPreference新preference( 需要v7.preference library配合)。

我们的界面现在应该是这样的,完全符合material desig。

1-L9R83CjU979qNaP73jLU3Q.png

不再有大号字体,category下的横线也没了。

我们可以在 Activity主题中修改colorAccent来改变CheckBox和Switch以及PreferenceCategory标题的颜色。

这只是创建material design 设置界面的第一步。当你打开EditText preference的Alert Dialog时,你会发现更多问题。下篇文章将讲解如何解决这些问题,以及如何自定义preference。

这个教程的第二部分在这里:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2017/0503/7903.html 

项目代码见 GitHub

感谢阅读,祝编码愉快!

原文:Building an Android Settings Screen (Part 1) 。

来自:设置(Settings)