android设置页面PreferenceFragmentCompat

说在前面

Android设置页面有通过SharedPreferences实现的,使用as自己创建的settingsactivity会报preferencefragment过时,但是使用PreferenceFragmentCompat又没法和创建好的页面使用,所以我只能通过创建一个activity通过引入fragment的方式创建PreferenceFragmentCompat

说在前面需要注意的是

虽然这个方法可以让设置的值全局获取到,但是经过我测试,新安装的程序如果没有打开过你写的这个activity,那么此时获取设置的值是获取不到的

简单创建

SettingActivity.java

创建了一个activity并且同时写了一个settingfragment,引入xml下的setting.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package cn.xwmdream.boxuegu;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceFragmentCompat;

public class SettingActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
}

public static class SettingFragment extends PreferenceFragmentCompat{

@Override
public void onCreatePreferences(Bundle bundle, String s) {
addPreferencesFromResource(R.xml.setting);
}
}
}

activity_setting.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SettingActivity">
<fragment
android:id="@+id/settingfragment"
android:name="cn.xwmdream.boxuegu.SettingActivity$SettingFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.constraint.ConstraintLayout>

setting.xml

最外层是一个设置屏幕,然后是一个分组,里面有一个开关

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.preference.PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.v7.preference.PreferenceCategory
android:title="第一个分组">
<android.support.v7.preference.SwitchPreferenceCompat
android:defaultValue="true"
android:key="firkey"
android:summary="我是详情"
android:title="我是标题"/>
</android.support.v7.preference.PreferenceCategory>
</android.support.v7.preference.PreferenceScreen>

效果图:

效果图

介绍各个控件

PreferenceCategory

PreferenceCategory是一个分组,把多个preference弄成一个区域,可以起一个小标题

属性表:

属性名 作用
title 分组的名称

SwitchPreferenceCompat(开关)

1
2
3
4
5
6
7
<android.support.v7.preference.SwitchPreferenceCompat
android:defaultValue="true"
android:key="firkey"
android:summaryOff="关闭了"
android:summaryOn="打开了"
android:summary="我是详情"
android:title="我是标题"/>

属性表:

属性名 作用
defaultValue 默认是开(true)还是关闭(false)
key 在sp文件中存储的key
summaryOff 当关闭时下面的小字
summaryOn 当开关打开时下面的小字
summary 设置下面的小字,优先级小于上面的两个属性
title 标题

效果

SwitchPreferenceCompat

MultiSelectListPreference(多选弹出框)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<MultiSelectListPreference
android:dialogTitle="弹出框显示标题"
android:entries="@array/show1"
android:entryValues="@array/array1"
android:key="key_multi"
android:summary="多选详情"
android:title="多选标题"
android:defaultValue="@array/ans1"
/>
<!--在string.xml中指定相应的值-->
<string-array name="show1">
<item>选项1</item>
<item>选项二</item>
<item>选项三</item>
</string-array>
<string-array name="array1">
<item>one</item>
<item>two</item>
<item>three</item>
</string-array>
<string-array name="ans1">
<item>one</item>
<item>two</item>
</string-array>

属性表:

属性名 作用
dialogTitle 弹出的标题
entries 多选框显示出来的字符串
entryValues 存储在sp中的值,entries中显示的值一一对应,比如选择了选项1,那么在sp中存一个值one
key 在sp中存储的key
summary 设置下面的小字
title 标题
defaultValue 默认值,是一个列表,存储的是entryValues,如果有值没有在entryValues中,那么这个值没有用

注意:虽然defaultValue如果设置了entryvalues没有的值时表面上什么都没选,但是在sp文件中已经记录了defaultValue的值,比如defaultValue记录了一个值onee,但是entryvalues没有这个值,则在弹出框中显示都没选,但是实际上在sp文件中已经记录了onee这个值
比如entryvalues中有三个值one,two,three,此时defaultvalue是onee,two,此时如果还什么都没选,弹出框只会在two前面打勾,sp文件中记录的是onee,two,如果现在在弹出框中把三个值都选了,那么在sp文件中是四个值onee,one,two,three

效果图

MultiSelectListPreference

ListPreference(单选弹出框)

1
2
3
4
5
6
7
8
9
<ListPreference
android:dialogTitle="单选弹出框"
android:entries="@array/show1"
android:entryValues="@array/array1"
android:key="key_list_pref"
android:summary="单选项情"
android:title="单选标题"
android:defaultValue="two"
/>

属性表:

属性名 作用
dialogTitle 弹出的标题
entries 多选框显示出来的字符串
entryValues 存储在sp中的值,entries中显示的值一一对应,比如选择了选项1,那么在sp中存一个值one
key 在sp中存储的key
summary 设置下面的小字
title 标题
defaultValue 默认值,是一个字符串,存储的是entryValues,如果有值没有在entryValues中或者没有这个属性,则什么都不默认选

注意:虽然defaultValue如果设置了entryvalues没有的值时表面上什么都没选,但是在sp文件中已经记录了defaultValue的值,比如defaultValue记录了一个值onee,但是entryvalues没有这个值,则在弹出框中显示都没选,但是实际上在sp文件中已经记录了onee这个值,但是如果从单选框中修改了值,那么sp文件中就会记录正常的entryvalues中的值,和上面多选的还是有区别的
比如entryvalues中有三个值one,two,three,此时defaultvalue是onee,此时如果还什么都没选,弹出框都不选,sp文件中记录的是onee,如果现在在选择了一个值,比如two,那么在sp文件中是正常的two

效果图

ListPreference

EditTextPreference(文字选项)

1
2
3
4
5
6
7
<EditTextPreference
android:defaultValue="我是默认值"
android:dialogTitle="我是弹出框"
android:key="key_edittext"
android:summary="我是详情"
android:title="我是标题"
/>

属性表:

属性名 作用
defaultValue 默认值
dialogTitle 弹出的标题
key 在sp中存储的key
summary 设置下面的小字
title 标题

效果图

EditTextPreference

CheckBoxPreference(选择开关)

1
2
3
4
5
6
7
<CheckBoxPreference
android:defaultValue="false"
android:key="key_checkbox"
android:summaryOff="我关闭了"
android:summaryOn="我打开了"
android:title="我是标题"
/>

属性表:

属性名 作用
defaultValue 默认是开(true)还是关闭(false)
key 在sp文件中存储的key
summaryOff 当关闭时下面的小字
summaryOn 当开关打开时下面的小字
summary 设置下面的小字,优先级小于上面的两个属性
title 标题

效果

CheckBoxPreference

SeekBarPreference(数值选择)

1
2
3
4
5
6
<android.support.v7.preference.SeekBarPreference
android:key="key_seekbar"
android:title="我是标题"
app:showSeekBarValue="false"
android:defaultValue="50"
/>

属性表:

属性名 作用
defaultValue 默认值
key 在sp文件中存储的key
title 标题
showSeekBarValue 是否显示数字

效果

SeekBarPreference

设置监听

对于每一个preference有一个监听方法,监听他们发生改变后的值
preference.setOnPreferenceChangeListener(Preference,Object);
其中object就是修改后的值,对应不同的preference它的类型是以下

preference 修改后的类型
SwitchPreferenceCompat true或者false
MultiSelectListPreference Set类型,是entryvalue的String集合
ListPreference String类型,是entryvalue中的String
CheckBoxPreference true或者false
SeekBarPreference 具体的数字
EditTextPreference 字符串

可以设置一个监听,当他们发生改变时在summery上修改成修改后的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object value) {
String stringValue = value.toString();
if (preference instanceof ListPreference) {
ListPreference listPreference = (ListPreference) preference;
int index = listPreference.findIndexOfValue(stringValue);
preference.setSummary(index >= 0 ? listPreference.getEntries()[index] : null);
}else if(preference instanceof MultiSelectListPreference){
StringBuffer summarys = new StringBuffer();
MultiSelectListPreference multiSelectListPreference = (MultiSelectListPreference)preference;
Set<String> values = (Set<String>)value;
for(String v : values){
int i = multiSelectListPreference.findIndexOfValue(v);
if(i>=0){
summarys.append(multiSelectListPreference.getEntries()[i]+",");
}
}
preference.setSummary(summarys.toString());
}
else {
preference.setSummary(stringValue);
}
return true;
}
};

在创建preferencefragment的时候只需要绑定一下这个方法即可

1
2
3
4
5
@Override
public void onCreatePreferences(Bundle bundle, String s) {
addPreferencesFromResource(R.xml.setting);
findPreference("key").setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
}

通过findPreference(String)方法可以通过preference的key找到对应的preference

经过我测试CheckBoxPreference和SwitchPreferenceCompat只要设置了summaryOff/On的属性,那么以上方法不会修改他们的summary,还是按照属性上的Off/On显示

通过设置打开另外的程序

打开一个网址

1
2
3
4
5
6
7
<PreferenceScreen
android:summary="xwmdream.cn"
android:title="打开官网">
<intent
android:action="android.intent.action.VIEW"
android:data="https://xwmdream.cn" />
</PreferenceScreen>

android:action
要分配的操作(按照 setAction() 方法)。
android:data
要分配的数据(按照 setData() 方法)。
android:mimeType
要分配的 MIME 类型(按照 setType() 方法)。
android:targetClass
组件名称的类部分(按照 setComponent() 方法)。
android:targetPackage
组件名称的软件包部分(按照 setComponent() 方法)。

也可以通过设置data为

1
android:data="market://details?id=cn.xwmdream.app"

打开应用商店

自定义设置