偏好设置
第一步,创建一个空的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"?>
9.3 在其中增加一个复选框的设置项,设置其5个属性
android:defaultValue="true" android:key="show_bass" android:summaryOff="隐藏" android:summaryOn="显示" android:title="是否显示BASS" >
十:将资源文件(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"?>
android:id="@+id/activity_setting" android:name="com.code369.test1.SettingFragment" android:layout_width="match_parent" android:layout_height="match_parent" >
十二:增加一个主题,在文件Res/values/styles.xml中,如果不增加这个主题,应用会崩溃。
至此,已经把设定的界面都实现了。接下来,要在主窗体中读取设定值,并让设定值起到作用。
一:在主窗体中,写一个函数,专门用来读取设定
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文件中增加列表偏好的定义
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"?> 三:读取列表偏好的值 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文件中增加该设定项
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; }