第一步,创建一个空的Activity,准备用它来放Fragment
public class SettingActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
第二步,在主窗体中加上一个菜单,来启用这个空窗体
第三步,在manifest中,设置SettingActivity的父窗体为主窗体
第四步,设置主窗体的launchMode="singleTop"
第五步,在空SettingActivity的onCreate加入下面的代码,使其中标题栏的左侧,出现一个返回按钮
ActionBar actionBar = this.getSupportActionBar();
// Set the action bar back button to look like an up button
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
第六步:响应该返回按钮,使其向上返回。
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
NavUtils.navigateUpFromSameTask(this);
}
return super.onOptionsItemSelected(item);
}
第七步:使用支持库7,注意小版本要和其它的小版本一致
implementation 'com.android.support:preference-v7:27.1.1'
然后同步
第八步:同步后,增加一个类,并按Ctrl+I,实现其抽象方法。
public class SettingFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
}
}
第九步:创建资源文件
9.1 在res目录下,创建一个xml目录
9.2 在xml目录下创建一个文件,fragment_setting.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
</PreferenceScreen>
9.3 在其中增加一个复选框的设置项,设置其5个属性
<CheckBoxPreference
android:defaultValue="true"
android:key="show_bass"
android:summaryOff="隐藏"
android:summaryOn="显示"
android:title="是否显示BASS"
></CheckBoxPreference>
十:将资源文件(fragment_setting.xml)和类(SettingFragment)结合起来
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.fragment_setting);
}
十一:将Fragment加入到空窗体
把activity_setting.xml的内容,换成一个fragment,,并设置它的name为SettingFragment (注意:是类的名字,而不是资源文件的名字)
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_setting"
android:name="com.code369.test1.SettingFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</fragment>
十二:增加一个主题,在文件Res/values/styles.xml中,如果不增加这个主题,应用会崩溃。
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
至此,已经把设定的界面都实现了。接下来,要在主窗体中读取设定值,并让设定值起到作用。
一:在主窗体中,写一个函数,专门用来读取设定
private void ReadSharedPreferences() {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean bValue = sharedPreferences.getBoolean("show_bass", true);
}
二:在主窗体实现OnSharedPreferenceChangeListener接口
public class VisualizerActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener
三:重载该接口的一个方法onSharedPreferenceChanged,让设定值生效
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(“show_bass”)){
boolean bValue = sharedPreferences.getBoolean("show_bass", true);
}
}
四:注册这个监听器(在读取设定那个函数)
private void ReadSharedPreferences() {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean bValue = sharedPreferences.getBoolean("show_bass", true);
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
}
此函数一般在onCreate要进行调用
五:注销这个接收器
protected void onDestroy() {
super.onDestroy();
PreferenceManager.getDefaultSharedPreferences(this)
.unregisterOnSharedPreferenceChangeListener(this);
}
列表偏好
一:在xml文件中增加列表偏好的定义
<ListPreference
android:defaultValue="@string/pref_color_red_value"
android:entries="@array/pref_color_option_labels"
android:entryValues="@array/pref_color_option_values"
android:key="@string/pref_color_key"
android:title="@string/pref_color_label" />
二: 在res/values下面新建一个arrays.xml,定义列表的值和显示内容
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Label ordering must match
values -->
<array
name="pref_color_option_labels">
<item>@string/pref_color_label_red</item>
<item>@string/pref_color_label_blue</item>
<item>@string/pref_color_label_green</item>
</array>
<array
name="pref_color_option_values">
<item>@string/pref_color_red_value</item>
<item>@string/pref_color_blue_value</item>
<item>@string/pref_color_green_value</item>
</array>
</resources>
三:读取列表偏好的值
private void loadColorFromPreferences(SharedPreferences sharedPreferences) {
mVisualizerView.setColor(sharedPreferences.getString
(“color“, ”red”));
}
四:偏好设置摘要(设置Fragment以编程方式更新摘要)
4.1 在SettingsFragment类中,实现接口(和主窗体一样,当设定改变时,更改摘要)nSharedPreferenceChangeListener
4.2 写一个函数,用来更改一个设定的摘要
private void setPreferenceSummary(Preference preference, String value) {
if (preference instanceof ListPreference) {
ListPreference listPreference = (ListPreference) preference;
int prefIndex = listPreference.findIndexOfValue(value);
if (prefIndex >= 0) {
listPreference.setSummary
(listPreference.getEntries()[prefIndex]);
}
}
}
4.3 在onCreatePreferences函数中,依次对每个设定项的摘要进行设定
SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
PreferenceScreen prefScreen = getPreferenceScreen();
int count = prefScreen.getPreferenceCount();
for (int i = 0; i < count; i++) {
Preference p = prefScreen.getPreference(i);
if (!(p instanceof CheckBoxPreference)) {
String value = sharedPreferences.getString(p.getKey(), "");
setPreferenceSummary(p, value);
}
}
4.4 重载接口的函数,在里面对改变的设定项,设置摘要
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Preference preference = findPreference(key);
if (null != preference) {
if (!(preference instanceof CheckBoxPreference)) {
String value = sharedPreferences.getString(preference.getKey(), "");
setPreferenceSummary(preference, value);
}
}
}
4.5 注册和销毁监听器
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}
public void onDestroy() {
super.onDestroy();
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}
文本偏好
一:在xml文件中增加该设定项
<EditTextPreference
android:defaultValue="@string/pref_size_default"
android:key="@string/pref_size_key"
android:title="@string/pref_size_label" />
二:在主窗体中,应该有一个专门读取所有设定的函数,在里面加上读取本参数的代码。
loadSizeFromSharedPreferences(sharedPreferences);
private void loadSizeFromSharedPreferences(SharedPreferences sharedPreferences) {
float minSize = Float.parseFloat(sharedPreferences.getString(“size”), “1.0” ));
。。。
}
三: 在onSharedPreferenceChanged事件中,对该项设定的改变也做出处理。
if (key.equals(getString(R.string.pref_size_key))) {
float minSize = Float.parseFloat(sharedPreferences.getString(“size”), “1.0” ));
。。。
}
四: 修改setPreferenceSummary函数,让它支持文本类型的偏好。
if (preference instanceof EditTextPreference) {
preference.setSummary(value);
这时会有一个问题,就是输入的内容不是数值时,数据类型转换会引发程序崩溃。
检查偏好设置是否合法
一:在类SettingsFragment中,实现接口Preference.OnPreferenceChangeListener
二: 在onCreatePreferences,把该事件附件到该设定项上
Preference preference = findPreference(getString(R.string.pref_size_key));
preference.setOnPreferenceChangeListener(this);
三:实现该接口函数,注意返回值,如果值不合法,返回false
public boolean onPreferenceChange(Preference preference, Object newValue) {
Toast error = Toast.makeText(getContext(), "Please select a number between 0.1 and 3", Toast.LENGTH_SHORT);
String sizeKey = getString(R.string.pref_size_key);
if (preference.getKey().equals(sizeKey)) {
String stringSize = (String) newValue;
try {
float size = Float.parseFloat(stringSize);
if (size > 3 || size <= 0) {
error.show();
return false;
}
} catch (NumberFormatException nfe) {
error.show();
return false;
}
}
return true;
}