创建 Android 设置界面 (第一部分)
几天前,我开始为我的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)
就如你看到的,里面存在大一号的字体,在分类标题下面有一条横线,这可不是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。
不再有大号字体,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。
感谢阅读,祝编码愉快!