Setting

应用通常包含设置,允许用户修改app的特征和行为。举例,一些app允许用户指定是否通知可用或者指定多久应用同步云端的数据。
如果想为我们的app提供设置,我们应该使用安卓的Preference API去建立一个接口,接口和其他安卓应用(包括系统设置)的用户体验一致。这个文档讨论如何建立app setting使用Preference API。
Overview
________________________________________
设置不是使用View对象去建立用户界面,而是使用我们在XML定义的Preference类的各种各样的子类建造的。
一个Preference对象是一个单独的设置的构件。每一个Preferece出现作为list的一个item,并且提供适当的UI让用户修改设置。举例,一个CheckBoxPreference创建一个list选项展示一个checkbox,一个ListPreference创建一个item,使用一系列选项打开一个对话框。
每一个我们添加的Preference有一个对应的键值对,系统用来在一个默认的SharedPreference文件为我们的app设置保存设置。当用户改变一个设置,系统为我们更新SharedPreference文件中相应的值。唯一我们需要直接和相关的SharedPreferences交互的时候是当我们需要读取这个值确定我们应用的行为。
为每一个设置保存在SharedPreference中的值可以是下面数据类型的一个:
Boolean
Float
Int
Long
String
String Set
    因为我们的app设置UI是使用Preference对象而不是View对象,我们需要使用一个专门的活动或碎片的子类去展示设置选项:
如果应用支持3.0(API 10)及以下的版本,我们必须构造活动作为PreferenceActivity类的扩展
在3.0之后,我们应该使用一个传统的持有一个展示app设置的PreferenceFragment的活动,然而我们也可以使用PreferenceActivity为大屏幕创建一个two-pane的布局当有多组设置的时候。
Preferences
我们app的每一个设置由一个Preference类的特殊子类展现。每一个子类包含一些核心属性,允许我们指定事情比如设置的标题和默认值。每一个子类也提供他们自己的专门的属性和用户界面。举例,下面展示了app设置消息的截图,每一个在设置屏幕的list项由一个不同的Preference对象支持。
 
几个最常用的设置如下:
CheckBoxPreference
    使用checkbox为一个要么可用要么不可用的设置展示一个选项。保存的值是boolean(选中是true)
ListPreference
使用一些radio button打开一个对话框。保存值可以是任何一个上面列出的支持的类型。
EditTextPreference
使用EditText部件打开一个对话框。保存值是string。


当然,内置的类不能适应我们应用的每一个需求,并且我们的应用需要一些专门的需求。比如,当前平台不提供Preference类选择数字或日期,我们需要自己定义Preference子类。在Building a Custom Preference.讨论。
自定义再说,先看内置的怎样的搞吧。




Preference类说明:
表示一个基本的Preference UI部件,被ListView的一个PreferenceActivity展示。这个类提供活动中要展示的View并且关联一个SharedPreferences保存和获取Preference数据。(提供两个东西,把活动和Preference关联起来,同时提供view)
当在一个XML文件制定一个Preference层级,每一个元素可以指向一个Preference子类,类似于view 层级和布局。
这个类包含一个key,作为一个到达SharedPreference的key。会到达子类去决定如何保存值。
This class contains a key that will be used as the key into the SharedPreferences. It is up to the subclass to decide how to store the value. 

Defining Preferences in XML
________________________________________
虽然我们可以在运行的时候实例化新的Preference对象,但是我们应该在XML中定义设置的list,使用Preference对象的层次结构。使用XML文件定义设置更好因为文件提供一个易读结构,容易更新。同时,我们的应用设置通常是提前确定的,虽然我们也可以在运行时修改。
每一个Preference子类可以使用一个匹配类名字XML元素声明,比如<CheckBoxPreference>.
我们必须在在res/xml目录保存xml文件。虽然我们可以随意命名,通常命名为preferences.xml.我们通常只需要一个文件,因为层级中的分支被使用嵌套的PreferenceScreen声明。
Each Preference subclass can be declared with an XML element that matches the class name, such as <CheckBoxPreference>.
Note: 如果想创建一个多面板布局,需要为每一个碎片提供独立的XML文件。
XML文件的根结点必须是一个<PreferenceScreen>元素。在这个元素中添加每一个Preference。每一个我们添加进<PreferenceScreen>元素的child作为设置list的一个单独item。
下面是例子:
 
    在这个例子中,有一个CheckBoxPreference和一个ListPreference。每一个都包含下面三个属性:


android:key
这个属性是为保存数据的preference必须的。他指定一个唯一的key(字符串)系统用来在SharedPreferences中保存这个设置的值。
唯一不需要指定这个属性的是当Preference是一个PreferenceCategory或PreferenceScreen,或者这个Preference指定一个intent去激活(使用<intent>元素),或者是一个要展示的碎片(有一个 android:fragment属性)。
The only instances in which this attribute is not required is when the preference is a PreferenceCategory or PreferenceScreen, or the preference specifies an Intent to invoke (with an <intent> element) or a Fragment to display (with an android:fragment attribute).
android:title
设置的标题(不过在哪里显示?)
android:defaultValue
指定系统应该保存在SharedPreferences文件中的初始值。我们应用为所以的设置提供默认值。



Using intents
某些情况下,我们可能想让一个Preference项打开一个不同的活动而不是设置屏幕,比如一个网络浏览器查看一个网页。要激活一个Intent当用户选择一个Preference项,添加一个<intent>元素作为对应的<Preference>元素的子类。
举例,下面是我们使用Preference打开一个web页面:
<Preference android:title="@string/prefs_web_page" >
    <intent android:action="android.intent.action.VIEW"
            android:data="http://www.example.com" />
</Preference>
    可以使用下面的属性创建隐式和显示意图
android:action
The action to assign, as per the setAction() method.
android:data
The data to assign, as per the setData() method.
android:mimeType
The MIME type to assign, as per the setType() method.
android:targetClass
The class part of the component name, as per the setComponent() method.
android:targetPackage
The package part of the component name, as per the setComponent() method


Creating a Preference Activity
________________________________________
    要在一个活动展示我们的设置,继承PreferenceActivity类。这是一个传统Activity类的扩展,以Preference对象的层级为基础展示一系列设置。PreferenceActivity自动保存每一个Preference关联的设置当用户改变的时候。
Note: 如果是3.0以上,使用PreferenceFragment。
    最重要的事要记住的是不在onCreate回调加载布局。相反,我们调用addPreferencesFromResource去添加我们在xml文件中定义的Preference到活动中,比如下面是空的最小的代码需求对 一个功能PreferenceActivity。
public class SettingsActivity extends PreferenceActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
    }
}
这对一些app是足够了,因为一旦用户修改一个Preference,系统保存改变到一个默认的SharedPreference文件,我们其他应用组件可以读当我们需要坚持用户的设置。许多app,然后,要求更多的代码去监听Preference的改变。下面监听,先看读


Reading Preferences
________________________________________
    默认,所有的应用Preferences被保存进一个文件,这个文件随时可以访问,只要在应用中调用静态方法PreferenceManager.getDefaultSharedPreferences().这个返回SharedPreferences对象,包含所有的关联到我们在PreferenceActivity使用的Preference对象的键值对。
By default, all your app's preferences are saved to a file that's accessible from anywhere within your application by calling the static method PreferenceManager.getDefaultSharedPreferences(). This returns the SharedPreferences object containing all the key-value pairs that are associated with the Preference objects used in your PreferenceActivity.
For example, here's how you can read one of the preference values from any other activity in your application:
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String syncConnPref = sharedPref.getString(SettingsActivity.KEY_PREF_SYNC_CONN, "");




Listening for preference changes
有些原因,我们可能想被通知当用户改变一个Preference。为了当任何一个Preference发生改变时接收一个回调,实现SharePreference.OnSharedPreferenceChangeListener接口,然后调用registerOnSharedPreferenceChangeListener为SharedPreferences对象注册监听器。
接口只有一个回调方法,onSharedPreferenceChanged,我们会发现这是最简单的实现一个接口作为活动的一部分。
public class SettingsActivity extends PreferenceActivity
                              implements OnSharedPreferenceChangeListener {
    public static final String KEY_PREF_SYNC_CONN = "pref_syncConnectionType";
    ...


    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
        String key) {
        if (key.equals(KEY_PREF_SYNC_CONN)) {
            Preference connectionPref = findPreference(key);
            // Set summary to be the user-description for the selected value
            connectionPref.setSummary(sharedPreferences.getString(key, ""));
        }
    }
}




在这个例子中,方法检查是否改变设置是为一个已知的Preference key。调用findPreference找到改变的Preference对象,这样他可以改变这个item的summary为一个用户选择的描述。那就是,当设置是一个ListPreference或者其他多选设置,我们应该调用setSummary当设置改变去展示当前的状态(比如睡眠设置在下图)
 
Note:推荐更新ListPreference的summary,每一次用户改变Preference去描述当前设置。
为了在活动中合适的生命周期管理,推荐分别注册和取消注册SharedPreferences.OnSharedPreferenceChangeListener在 onResume() and onPause() 回调方法。
@Override
protected void onResume() {
    super.onResume();
    getPreferenceScreen().getSharedPreferences()
            .registerOnSharedPreferenceChangeListener(this);
}


@Override
protected void onPause() {
    super.onPause();
    getPreferenceScreen().getSharedPreferences()
            .unregisterOnSharedPreferenceChangeListener(this);
}
Caution: 当我们调用registerOnSharedPreferenceChangeListener,preference manager不保存监听器的一个strong reference,我们必须保存一个strong reference为这个监听器,或者会容易被垃圾回收。推荐保存一个监听器的引用,只要需要就会存在。
When you call registerOnSharedPreferenceChangeListener(), the preference manager does not currently store a strong reference to the listener. You must store a strong reference to the listener, or it will be susceptible to garbage collection. We recommend you keep a reference to the listener in the instance data of an object that will exist as long as you need the listener.


下面的例子,调用者不保存监听器的一个reference。结果,监听器会被放到垃圾回收,在将来某些不确定的时候为失败:
prefs.registerOnSharedPreferenceChangeListener(
  // Bad! The listener is subject to garbage collection!
  new SharedPreferences.OnSharedPreferenceChangeListener() {
  public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    // listener implementation
  }
});


    相反,保存一个参考给监听器在一个对象的实例数据属性,会存在只要监听器被需要:
Instead, store a reference to the listener in an instance data field of an object that will exist as long as the listener is needed:
SharedPreferences.OnSharedPreferenceChangeListener listener =
    new SharedPreferences.OnSharedPreferenceChangeListener() {
  public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    // listener implementation
  }
};
prefs.registerOnSharedPreferenceChangeListener(listener);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值