今天跟大家唠唠我最近折腾的 PreferenceScreen,这玩意儿,说白就是个设置界面生成器,能让你轻松搞出各种设置选项,不用自己一点点写布局,省事儿不少。
我寻思着给自己的App加个设置页面,让用户能自定义一些东西。手动写布局太麻烦,就想看看有没有什么更简单的方法。网上搜一圈,发现 PreferenceScreen 这玩意儿,看着还挺靠谱,就决定上手试试。
我新建一个 xml 文件,专门用来放 PreferenceScreen 的配置。这文件就跟写布局一样,不过里面放的不是 TextView、Button,而是 Preference、CheckBoxPreference、EditTextPreference 这些东西。
xml
android:key="enable_notifications" android:title="开启通知" android:summary="接收最新消息通知"/> android:key="nickname" android:title="昵称" android:summary="设置你的昵称"/>
你看,CheckBoxPreference 就是个复选框,EditTextPreference 就是个可以输入文字的输入框。每个 Preference 都有一个 key,这个 key 后面会用到,用来保存和读取设置的值。
然后,在 Activity 里面,我得把这个 xml 文件加载到 PreferenceScreen 上。我先是尝试直接用 PreferenceActivity,结果发现这玩意儿都过时,官方不推荐用。
后来我改用 PreferenceFragmentCompat,这才是正道。
java
public class SettingsFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(*, rootKey);
这段代码很简单,就是把 xml 文件加载到 PreferenceFragmentCompat 上。
我就遇到一个问题:怎么读取用户设置的值? 比如,用户开启通知,我怎么知道?
这就得用到 SharedPreferences 。 PreferenceScreen 会自动把用户的设置保存到 SharedPreferences 里面,我们只需要从 SharedPreferences 里面读取就行。
java
SharedPreferences sharedPreferences = *(getContext());
boolean enableNotifications = *("enable_notifications", true); // 默认开启通知
String nickname = *("nickname", "默认昵称");
这里,getBoolean() 和 getString() 方法就是用来读取 SharedPreferences 里面的值。第一个参数是 key,就是 xml 文件里面设置的 key,第二个参数是默认值,如果 SharedPreferences 里面没有这个 key,就返回默认值。
做到这里,基本的功能就实现。但是,我发现 PreferenceScreen 默认的样式有点丑,我想自定义一下。
这就比较麻烦,PreferenceScreen 的自定义性比较差,不太容易改样式。
我尝试几种方法:
自定义 Preference 的布局文件:这个方法可以改单个 Preference 的样式,但是比较繁琐,每个 Preference 都要写一个布局文件。 使用主题:这个方法可以改全局的样式,但是不太灵活,只能改一些简单的颜色和字体。我选择自定义 Preference 的布局文件,虽然麻烦点,但是可以更精细地控制样式。
我新建一个 xml 文件,作为自定义 Preference 的布局:
xml
android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp"> android:id="@android:id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="18sp" android:textColor="@android:color/black"/> android:id="@android:id/summary" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="14sp" android:textColor="@android:color/darker_gray"/>
然后,在 Java 代码里面,继承 Preference 类,重写 onBindView() 方法,把自定义的布局设置进去:
java
public class CustomPreference extends Preference {
public CustomPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setLayoutResource(*_preference); // 设置自定义布局
@Override
protected void onBindView(View view) {
*(view);
// 在这里可以获取布局里面的 View,并进行自定义设置
TextView titleView = *(android.*);
TextView summaryView = *(android.*);
// 设置字体颜色,大小等等
*(12);
在 PreferenceScreen 的 xml 文件里面,使用 CustomPreference:
xml
<*.CustomPreference
android:key="custom_preference"
android:title="自定义选项"
android:summary="这是一个自定义的选项"/>
这样,就可以使用自定义的样式。
PreferenceScreen 还是挺好用的,能快速生成设置界面。但是,自定义性比较差,如果需要更复杂的样式,就需要自己写布局或者自定义 Preference 类。
整个过程就是这样,从一开始的一窍不通,到能勉强用起来,还是学到不少东西。希望我的分享能帮到大家,少走一些弯路。