应用通常包括允许用户修改应用特性和行为的设置
例如,有些应用允许用户指定是否启用通知,或指定应用与云端同步数据的频率
若要为应用提供设置,您应该使用 Android 的 Preference API 构建一个与其他 Android 应用中的用户体验一致的界面(包括系统设置)。本文旨在介绍如何使用 Preference API 构建应用设置
- 首先要在res文件夹下新建一个xml文件夹,然后新建一个xml文件,一般为preference
- 每个xml文件的根节点必须为一个PreferenceScreen,在PreferenceScreen里面添加的每个Preference将视为一个单独的项,可使用PreferenceCategory进行分组
android:key
对于要保留数据值的首选项,必须拥有此属性。它指定系统在将此设置的值保存在 SharedPreferences 中时所用的唯一键(字符串)。
不需要此属性的唯一情形是:首选项是 PreferenceCategory 或PreferenceScreen,或者首选项指定要调用的 Intent(使用 元素)或要显示的 Fragment(使用 android:fragment 属性)。
android:title
此属性为设置提供用户可见的名称。
android:defaultValue
此属性指定系统应该在 SharedPreferences 文件中设置的初始值。您应该为所有设置提供默认值。
- 将Preference放进Preference中后,每两个Preference之间将会由横线隔开
- 每个设置界面要依托在一个Activity或者Fragment上,使用Activity的话要继承PreferenceActivity,使用Fragment的话要继承PreferenceFragment,两种情况下都不需要在加载视图,直接使用设置列表,在onCreate()中添加需要的设置列表
1
| addPreferencesFromResource(R.xml.preferences);
|
设置默认值
您创建的首选项可能会为应用定义一些重要行为,因此在用户首次打开应用时,您有必要使用每个 Preference 的默认值初始化相关的 SharedPreferences 文件。
首先,您必须使用 android:defaultValue 属性为 XML 文件中的每个 Preference 对象指定默认值。该值可以是适合相应 Preference 对象的任意数据类型。例如:
然后,通过应用的主 Activity(以及用户首次进入应用所藉由的任何其他 Activity)中的 onCreate() 方法调用 setDefaultValues():
PreferenceManager.setDefaultValues(this, R.xml.advanced_preferences, false);
在 onCreate() 期间调用此方法可确保使用默认设置正确初始化应用,而应用可能需要读取这些设置以确定某些行为(例如,是否在蜂窝网络中下载数据)。
此方法采用三个参数:
应用 Context。
要为其设置默认值的首选项 XML 文件的资源 ID。
一个布尔值,用于指示是否应该多次设置默认值。
如果该值为 false,则仅当过去从未调用此方法时(或者默认值共享首选项文件中的 KEY_HAS_SET_DEFAULT_VALUES为 false 时),系统才会设置默认值。
只要将第三个参数设置为 false,您便可在每次启动 Activity 时安全地调用此方法,而不必通过重置为默认值来替代用户已保存的首选项。 但是,如果将它设置为 true,则需要使用默认值替代之前的所有值。
PreferenceManager.setDefaultValues(this, R.xml.advanced_preferences, false);
读取首选项
默认情况下,应用的所有首选项均保存到一个可通过调用静态方法 PreferenceManager.getDefaultSharedPreferences() 从应用内的任何位置访问的文件中。 这将返回 SharedPreferences 对象,其中包含与 PreferenceActivity 中所用 Preference 对象相关的所有键值对。
例如,从应用中的任何其他 Activity 读取某个首选项值的方法如下:
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String syncConnPref = sharedPref.getString(SettingsActivity.KEY_PREF_SYNC_CONN, "");
- 一般在Activity的onResume()和onPause()分别注册和注销SharedPreferences.OnSharedPreferenceChangeListener
以下是详细代码
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| package www.lollipopstudio.top.settingpreference;
import android.content.SharedPreferences; import android.os.Bundle; import android.preference.EditTextPreference; import android.preference.ListPreference; import android.preference.MultiSelectListPreference; import android.preference.PreferenceActivity; import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout;
import static www.lollipopstudio.top.settingpreference.R.xml.preference;
public class MainActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent(); View bar = LayoutInflater.from(this).inflate(R.layout.toolbar, root, false); root.addView(bar, 0); android.support.v7.widget.Toolbar toolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.toolbar); toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } });
addPreferencesFromResource(preference); }
@Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { switch (key) { case "switch": case "ringtone": case "checkbox": break; case "multi": setMultiListPreferenceSummary(key); break; case "single": setListPreferenceSummary(key); break; case "editText": setText(key); break; }
}
@Override protected void onResume() { super.onResume(); getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); setListPreferenceSummary("single"); setMultiListPreferenceSummary("multi"); setText("editText"); }
@Override protected void onPause() { super.onPause(); getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); }
private void setListPreferenceSummary(String preferenceKey) { ListPreference preference = (ListPreference)findPreference(preferenceKey); preference.setSummary(preference.getEntry()); }
private void setMultiListPreferenceSummary(String preferenceKey) { MultiSelectListPreference preference = (MultiSelectListPreference)findPreference(preferenceKey); preference.setSummary(preference.getValues().toString()); }
private void setText(String preferenceKey) { EditTextPreference preference = (EditTextPreference)findPreference(preferenceKey); preference.setSummary(preference.getText()); } }
|
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceCategory android:title="Something">
<CheckBoxPreference android:defaultValue="true" android:key="checkBoxFirst" android:icon="@drawable/ic_build_black_24dp" android:title="CheckBox"/>
<SwitchPreference android:icon="@drawable/ic_album_black_24dp" android:defaultValue="false" android:key="switch" android:title="Switch preference"/>
</PreferenceCategory>
<PreferenceCategory android:title="Select"> <ListPreference android:defaultValue="A" android:entries="@array/singleSelect" android:entryValues="@array/singleSelectValues" android:key="single" android:title="Single select"/>
<MultiSelectListPreference android:entries="@array/singleSelect" android:entryValues="@array/singleSelectValues" android:key="multi" android:title="Multi select list preference"/>
</PreferenceCategory>
<PreferenceCategory android:title="OpenSettingInOtherScreen">
<PreferenceScreen android:title="OtherScreen"> <Preference android:layout="@layout/toolbar"/> <CheckBoxPreference android:defaultValue="true" android:key="checkbox" android:title="Checkbox"> </CheckBoxPreference>
</PreferenceScreen>
</PreferenceCategory>
<PreferenceCategory android:title="OpenOtherActivity"> <Preference android:title="OpenOtherActivity"> <intent android:action="android.intent.action.otherAcyivity"/> </Preference> </PreferenceCategory>
<PreferenceCategory android:title="Other">
<Preference android:title="OpenWeb"> <intent android:action="android.intent.action.VIEW" android:data="http://www.exale.com"/> </Preference>
<RingtonePreference android:defaultValue="" android:key="ringtone" android:title="Ringtone preference"/>
<EditTextPreference android:defaultValue="describe" android:key="editText" android:title="EditText"/> </PreferenceCategory>
</PreferenceScreen>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <?xml version="1.0" encoding="utf-8"?> <resources>
<string-array name="singleSelect"> <item name="A">A</item> <item name="B">B</item> <item name="C">C</item> </string-array>
<string-array name="singleSelectValues"> <item name="A">A</item> <item name="B">B</item> <item name="C">C</item> </string-array>
</resources>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="?attr/actionBarSize" android:background="?attr/colorPrimary" app:navigationIcon="?attr/homeAsUpIndicator" app:title="setting2"> </android.support.v7.widget.Toolbar> </android.support.design.widget.AppBarLayout>
|