安卓 用户界面 Preference 教程翻译

本文详细介绍Android偏好设置(Preference)的使用方法,包括设置概述、使用XML定义偏好设置、创建PreferenceActivity及PreferenceFragment等内容,帮助开发者更好地理解并运用Android偏好设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Settings

In this document

[译注:以下是目录,没翻译,保留链接]

1. Overview 

1. Preferences

1. Defining Preferences in XML 

1. Creating setting groups

2. Using intents

1. Creating a Preference Activity

2. Using Preference Fragments

3. Setting Default Values

4. Using Preference Headers 

1. Creating the headers file

2. Displaying the headers

3. Supporting older versions with preference headers

1. Reading Preferences 

1. Listening for preference changes

1. Managing Network Usage

2. Building a Custom Preference 

1. Specifying the user interface

2. Saving the setting's value

3. Initializing the current value

4. Providing a default value

5. Saving and restoring the Preference's state

Key classes

1. Preference

2. PreferenceActivity

3. PreferenceFragment

See also

1. Settings design guide

Applications often include settings that allow users to modify app features and behaviors. For example, some apps allow users to specify whether notifications are enabled or specify how often the application syncs data with the cloud.

[译文:应用程序经常包含一些设置数据,以便用户可以调整APP的功能和行为。例如,一些APP允许用户指定是否使用通知消息,指定和云端多久同步一次数据等。]

If you want to provide settings for your app, you should use Android's Preference APIs to build an interface that's consistent with the user experience in other Android apps (including the system settings). This document describes how to build your app settings using Preference APIs.

[译文:如果你想让你的APP有配置功能,你应该使用Android的 Preference API,来建立一个和其他Android APP具有相同用户体验的界面。这篇文档描述了如何使用Preference API建立你的APP。]

Settings Design

[译文:配置的设计]

For information about how to design your settings, read the Settings design guide.

[译文:关于如何设计你的配置,请参阅Settings 设计教程]

https://developer.android.com/images/ui/settings/settings.png

Figure 1. Screenshots from the Android Messaging app's settings. Selecting an item defined by a Preference opens an interface to change the setting.

[译文:图一,从Android消息APP截取的设置截屏。选择一个用Preference定义的条目,会打开一个界面来更改设置]

Overview 

 

Instead of using View objects to build the user interface, settings are built using various subclasses of the Preference class that you declare in an XML file.

[译文:与通常使用View来建立用户界面不同,‘设置’使用Preference的若干子类来建立界面,它们是声明在某个XML文件里的]

A Preference object is the building block for a single setting. Each Preference appears as an item in a list and provides the appropriate UI for users to modify the setting. For example, a CheckBoxPreference creates a list item that shows a checkbox, and a ListPreference creates an item that opens a dialog with a list of choices.

[译文:一个Preference对象就是某个配置项的逻辑块。每个Preference呈现为一个列表中的一个条目,并为用户提供适当的UI来更改配置]

Each Preference you add has a corresponding key-value pair that the system uses to save the setting in a default SharedPreferences file for your app's settings. When the user changes a setting, the system updates the corresponding value in the SharedPreferences file for you. The only time you should directly interact with the associated SharedPreferences file is when you need to read the value in order to determine your app's behavior based on the user's setting.

[译文:每个你添加的Preference,系统都会在一个默认的SharedPreference文件中,有一个对应的key-value对来为你的APP配置保存数据。当用户更改某个配置,系统为你在SharedPreferences文件中更新对应的值。你唯一需要直接和相关的SharedPReference交互的时刻,就是当你需要读取这些数据,以根据用户设置来确定APP的行为时。]

The value saved in SharedPreferences for each setting can be one of the following data types:

[译文:存于SharedPreferences的数据,应该是以下数据类型之一。]

· Boolean

· Float

· Int

· Long

· String

· String Set

Because your app's settings UI is built using Preference objects instead of View objects, you need to use a specialized Activity or Fragment subclass to display the list settings:

[译文:因为你的APP配置界面是使用Preference而不是View对象建立的,你需要使用特定的Activity或者Fragment的子类来显示配置列表]

· If your app supports versions of Android older than 3.0 (API level 10 and lower), you must build the activity as an extension of the PreferenceActivity class.

[译文:如果你的APP支持Android 3.0以下,你必须扩展PreferenceActivity来建立你的Activity]

· On Android 3.0 and later, you should instead use a traditional Activity that hosts a PreferenceFragment that displays your app settings. However, you can also use PreferenceActivity to create a two-pane layout for large screens when you have multiple groups of settings.

[译文:Android3.0以后,你应该使用一个包含PreferenceFragment的传统的Activity。此外,你还可以使用PreferenceActivity,在你有多个配置组的时候,在大屏幕设备上创建一个‘双面板’的布局。]

How to set up your PreferenceActivity and instances of PreferenceFragment is discussed in the sections about Creating a Preference Activity and Using Preference Fragments.

[译文:如何建立你的PreferenceActivity和PreferenceFragment实例,在 ‘创建PreferenceActivity’和‘使用Preference Fragments’这两节里阐述。]

Preferences

Every setting for your app is represented by a specific subclass of the Preference class. Each subclass includes a set of core properties that allow you to specify things such as a title for the setting and the default value. Each subclass also provides its own specialized properties and user interface. For instance, figure 1 shows a screenshot from the Messaging app's settings. Each list item in the settings screen is backed by a different Preference object.

[译文:你的APP里的每个配置项,都是由一个Preference子类展现的。每个子类都包含一套通用的核心属性,让你可以指定一些内容,比如配置的标题啊,缺省值啊什么的。每个子类还会提供一些特别的属性和界面。举例说明,图一显示了消息APP配置的一个截屏。配置界面中的每个列表条目,都是由各自不同的Preference对象在背后默默支持的]

A few of the most common preferences are:

[译文:一些常见的Prefrence有:]

CheckBoxPreference

Shows an item with a checkbox for a setting that is either enabled or disabled. The saved value is a boolean (true if it's checked).

[译文:为一个‘开关’配置项显示一个带Checkbox的条目。保存的值是布尔值。被选中就是true。]

ListPreference

Opens a dialog with a list of radio buttons. The saved value can be any one of the supported value types (listed above).

[译文:打开一个单选按钮的列表对话框。保存的结果可以是任何一种支持的数据类型。(前面列出的那些)]

EditTextPreference

Opens a dialog with an EditText widget. The saved value is a String.

[译文:打开一个带EditText的小窗口。保存的值是String]

See the Preference class for a list of all other subclasses and their corresponding properties.

[译文:查看Preference API可以获得所有子类和他们的属性。]

Of course, the built-in classes don't accommodate every need and your application might require something more specialized. For example, the platform currently does not provide a Preference class for picking a number or a date. So you might need to define your own Preference subclass. For help doing so, see the section about Building a Custom Preference.

[译文:诚然,内置的实现无法满足所有的需求,你的应用可能有更特别的需要。例如,目前平台没有提供选择一个数字或者日期的Preference子类。所以你会需要定制你自己的Preference子类。相关的帮助,请参看‘建立自定义Preference’]

Defining Preferences in XML

[译文:使用XML定义Preferences]

 

Although you can instantiate new Preference objects at runtime, you should define your list of settings in XML with a hierarchy of Preference objects. Using an XML file to define your collection of settings is preferred because the file provides an easy-to-read structure that's simple to update. Also, your app's settings are generally pre-determined, although you can still modify the collection at runtime.

[译文:即便你可以在运行时,使用代码建立Preference对象,你还是应该在XML中使用一个具有层级结构的Preference对象来定义你的配置数据列表。使用XML定义你的配置集更好,因为文件有易读的结构,很容易更新。此外,你的APP配置通常是预先确定的。当然,你尽可以运行时动态修改配置集。]

Each Preference subclass can be declared with an XML element that matches the class name, such as <CheckBoxPreference>.

You must save the XML file in the res/xml/ directory. Although you can name the file anything you want, it's traditionally named preferences.xml. You usually need only one file, because branches in the hierarchy (that open their own list of settings) are declared using nested instances of PreferenceScreen.

[译文:每个Preference子类都可以使用一个XML元素来声明,这个元素需要匹配它的类名。例如<checkBoxPreference>. 你必须把这个XML文件保存在 res/xml 目录下。这个文件名可以任意,通常使用名字‘preferences.xml’。通常你只需要一个文件,因为层级结构中的分支(这意味着他们有自己的配置列表)使用嵌套的PreferenceScreen来声明]

Note: If you want to create a multi-pane layout for your settings, then you need separate XML files for each fragment.

[译文:Note: 你要是想建立一个多片区的布局,你需要给每个fragment分别建立XML]

The root node for the XML file must be a <PreferenceScreen> element. Within this element is where you add each Preference. Each child you add within the <PreferenceScreen> element appears as a single item in the list of settings.

[译文:XML根元素必须是 <PrefrenceScreen>. 你的每个Preference都在这个元素内。每个PreferenceScreen的子元素都会在配置列表里呈现为一个单独的条目]

For example:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <CheckBoxPreference
        android:key="pref_sync"
        android:title="@string/pref_sync"
        android:summary="@string/pref_sync_summ"
        android:defaultValue="true" />
    <ListPreference
        android:dependency="pref_sync"
        android:key="pref_syncConnectionType"
        android:title="@string/pref_syncConnectionType"
        android:dialogTitle="@string/pref_syncConnectionType"
        android:entries="@array/pref_syncConnectionTypes_entries"
        android:entryValues="@array/pref_syncConnectionTypes_values"
        android:defaultValue="@string/pref_syncConnectionTypes_default" />
</PreferenceScreen>

In this example, there's a CheckBoxPreference and a ListPreference. Both items include the following three attributes:

[译文:在这个例子里,有一个CheckBoxPrefrence和一个ListPreference。他们都包含以下3个属性:]

android:key

This attribute is required for preferences that persist a data value. It specifies the unique key (a string) the system uses when saving this setting's value in the SharedPreferences.

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:key 这个属性对需要持久化数据的Preference是必须的。它指定了一个独一无二的Key(是个字符串),系统使用它在SharedPreference里保存数据的值。 唯一不需要这个属性的特例是PrefrenceCategory或者PreferenceScreen。或者Prefrence指定调用了一个Intent(就是有一个<intent>元素)或者显示一个Fragment(就是有一个android:fragment属性)]

android:title

This provides a user-visible name for the setting.

[译文:android:title 这个指定了用户可见的配置项的名字]

android:defaultValue

This specifies the initial value that the system should set in the SharedPreferences file. You should supply a default value for all settings.

[译文:android:defaultValue 缺省值。你应该给所有的配置都指定缺省值]

For information about all other supported attributes, see the Preference (and respective subclass) documentation.

https://developer.android.com/images/ui/settings/settings-subscreen.png

Figure 2. Setting categories with titles.
1. The category is specified by the <PreferenceCategory> element.
2. The title is specified with the android:title attribute.

[译文:图2. 带标题的配置分组 1. 配置分组使用 <PreferenceCategory>标签定义。2. 标题是用<android:title>属性指定的]

When your list of settings exceeds about 10 items, you might want to add titles to define groups of settings or display those groups in a separate screen. These options are described in the following sections.

[译文:当你的配置列表超过10项,你会想给配置项分组并定义一个名字或者分屏显示。这些选项在羡慕几章描述]

Creating setting groups

If you present a list of 10 or more settings, users may have difficulty scanning, comprehending, and processing them. You can remedy this by dividing some or all of the settings into groups, effectively turning one long list into multiple shorter lists. A group of related settings can be presented in one of two ways:

[译文:如果你有超过10项配置,用户很难查看,综合并处理他们。你可以改进一下,把他们分成组,有效的把一个长长的列表变成几个短列表。一组相关的配置可以有两种展示的方式]

· Using titles

· Using subscreens

[译文:如果你有超过10项配置,用户很难查看,综合并处理他们。你可以改进一下,把他们分成组,有效的把一个长长的列表变成几个短列表。一组相关的配置可以有两种展示的方式: 1-使用标题,2-使用分屏]

You can use one or both of these grouping techniques to organize your app's settings. When deciding which to use and how to divide your settings, you should follow the guidelines in Android Design's Settings guide.

[译文:你可以使用一个或者全部分组技术来组织你的APP的配置项。在决定了使用哪个方法,以及如何划分配置组后,你可以依照Android设计教程‘Settings’来做]

Using titles

[译文:使用标题]

If you want to provide dividers with headings between groups of settings (as shown in figure 2), place each group of Preference objects inside a PreferenceCategory.

[译文:如果你想在配置分组中提供‘题头’(如图2所示),把每个组的Preference对象们都放到一个PreferenceCategory里]

For example:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory
        android:title="@string/pref_sms_storage_title"
        android:key="pref_key_storage_settings">
        <CheckBoxPreference
            android:key="pref_key_auto_delete"
            android:summary="@string/pref_summary_auto_delete"
            android:title="@string/pref_title_auto_delete"
            android:defaultValue="false"... />
        <Preference
            android:key="pref_key_sms_delete_limit"
            android:dependency="pref_key_auto_delete"
            android:summary="@string/pref_summary_delete_limit"
            android:title="@string/pref_title_sms_delete"... />
        <Preference
            android:key="pref_key_mms_delete_limit"
            android:dependency="pref_key_auto_delete"
            android:summary="@string/pref_summary_delete_limit"
            android:title="@string/pref_title_mms_delete" ... />
    </PreferenceCategory>
    ...
</PreferenceScreen>

Using subscreens

[译文:使用分屏]

If you want to place groups of settings into a subscreen (as shown in figure 3), place the group of Preference objects inside a PreferenceScreen.

[译文:如果你想把一组配置放到更低层屏幕显示(如图3),把这组Preference对象们都放到一个PreferenceScreen里]

https://developer.android.com/images/ui/settings/settings-subscreen.png

Figure 3. Setting subscreens. The <PreferenceScreen> element creates an item that, when selected, opens a separate list to display the nested settings.

For example:

<PreferenceScreen  xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- opens a subscreen of settings -->
    <PreferenceScreen
        android:key="button_voicemail_category_key"
        android:title="@string/voicemail"
        android:persistent="false">
        <ListPreference
            android:key="button_voicemail_provider_key"
            android:title="@string/voicemail_provider" ... />
        <!-- opens another nested subscreen -->
        <PreferenceScreen
            android:key="button_voicemail_setting_key"
            android:title="@string/voicemail_settings"
            android:persistent="false">
            ...
        </PreferenceScreen>
        <RingtonePreference
            android:key="button_voicemail_ringtone_key"
            android:title="@string/voicemail_ringtone_title"
            android:ringtoneType="notification" ... />
        ...
    </PreferenceScreen>
    ...
</PreferenceScreen>

Using intents

[译文:使用Intents]

In some cases, you might want a preference item to open a different activity instead of a settings screen, such as a web browser to view a web page. To invoke an Intent when the user selects a preference item, add an <intent> element as a child of the corresponding <Preference> element.

[译文:在有些场合,你可能希望你的Preference打开一个Activity而不是配置界面,比如一个web浏览器查看一个web页面。要在点击时调用一个Intent,就添加一个<intent>元素作为Preference的子元素。]

For example, here's how you can use a preference item to open a web page:

<Preference android:title="@string/prefs_web_page" >
    <intent android:action="android.intent.action.VIEW"
            android:data="http://www.example.com" />
</Preference>

You can create both implicit and explicit intents using the following attributes:

[译文:你可以使用下面的属性来显式的或者隐式的创建intent]

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

[译文:创建一个Preference Activity]

 

To display your settings in an activity, extend the PreferenceActivity class. This is an extension of the traditional Activity class that displays a list of settings based on a hierarchy of Preference objects. The PreferenceActivity automatically persists the settings associated with each Preference when the user makes a change.

[译文:要在一个Activity里显示你的配置,扩展PreferenceActivity类。这个是传统的Activity类的扩展,它可以基于层级结构的Preference对象显示配置项列表。PreferenceActivity自动的将每个Preference相关的配置项,在用户更改后持久化。]

Note: If you're developing your application for Android 3.0 and higher, you should instead use PreferenceFragment. Go to the next section about Using Preference Fragments.

[译文:Note:如果在Android3.0以上开发,你应该用PrefrenceFragment代替。参加下一节:使用Preference Fragment]

The most important thing to remember is that you do not load a layout of views during the onCreate() callback. Instead, you call addPreferencesFromResource() to add the preferences you've declared in an XML file to the activity. For example, here's the bare minimum code required for a functional PreferenceActivity:

[译文:千万要记住,在OnCreate()回调中,不要加载一个视图的layout。而是应该调用 addPReferenceFromResource()来加载你在XML声明的Preferences到你的Activity。例如,下面是一段可运行的PreferenceActivity的最低限度的代码]

public class SettingsActivity extends PreferenceActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
    }
}

This is actually enough code for some apps, because as soon as the user modifies a preference, the system saves the changes to a default SharedPreferences file that your other application components can read when you need to check the user's settings. Many apps, however, require a little more code in order to listen for changes that occur to the preferences. For information about listening to changes in the SharedPreferences file, see the section about Reading Preferences.

[译文:对某些APP,这就足够了,因为一旦用户更改了一个Preference,系统就把更改保存到一个确实的SharedPReferences文件,你应用中的其他组件可以在需要的时候读取它。很多APP,不可否认,需要更多一点代码,监听Preference的更改。关于监听,参阅‘读取Preferences’一节]

Using Preference Fragments

[译文:使用Preference Fragment]

 

If you're developing for Android 3.0 (API level 11) and higher, you should use a PreferenceFragment to display your list of Preference objects. You can add a PreferenceFragment to any activity—you don't need to use PreferenceActivity.

[译文:如果使用Android3.0以上开发,应该使用PrefrenceFragment来显示Preference列表。你可以把PreferenceFragment加到任何一个Activity,而不必使用PreferenceActivity]

Fragments provide a more flexible architecture for your application, compared to using activities alone, no matter what kind of activity you're building. As such, we suggest you use PreferenceFragment to control the display of your settings instead of PreferenceActivity when possible.

[译文:相对于单单使用activity,Fragment提供更灵活的结构,无论你在构建的是什么类型的Activity。因此我们建议尽可能的使用PreferenceFragment替代PreferenceActivity来显示你的配置]

Your implementation of PreferenceFragment can be as simple as defining the onCreate() method to load a preferences file with addPreferencesFromResource(). For example:

[译文:你实现的PreferenceFragment可以简单的在OnCreate里加载一个preference文件。]

public static class SettingsFragment extends PreferenceFragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Load the preferences from an XML resource
        addPreferencesFromResource(R.xml.preferences);
    }
    ...
}

You can then add this fragment to an Activity just as you would for any other Fragment. For example:

[译文:你可以把这个Fragment像其他Fragment一样添加到Activity中]

public class SettingsActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Display the fragment as the main content.
        getFragmentManager().beginTransaction()
                .replace(android.R.id.content, new SettingsFragment())
                .commit();
    }
}

Note: A PreferenceFragment doesn't have a its own Context object. If you need a Context object, you can call getActivity(). However, be careful to call getActivity() only when the fragment is attached to an activity. When the fragment is not yet attached, or was detached during the end of its lifecycle, getActivity() will return null.

[译文:Note:一个PreferenceFragment没有自己的Contect对象。如果你需要一个Context对象,你可以调用getActivity(). 不过要小心,仅在Fragment附件在一个Activity后,调用getActivity(). 当fragment还没添加上,或者在生命周期结束时已经取消关联了,getActivity()会返回null]

Setting Default Values

 

The preferences you create probably define some important behaviors for your application, so it's necessary that you initialize the associated SharedPreferences file with default values for each Preference when the user first opens your application.

[译文:缺省值很重要]

The first thing you must do is specify a default value for each Preference object in your XML file using the android:defaultValue attribute. The value can be any data type that is appropriate for the corresponding Preference object. For example:

[译文:首先要做的,是在XML中用android:defaultValue给每个Preference对象指定缺省值。值可以是相关Preference对象任何适当的数据类型。]

<!-- default value is a boolean -->
<CheckBoxPreference
    android:defaultValue="true"
    ... />

<!-- default value is a string -->
<ListPreference
    android:defaultValue="@string/pref_syncConnectionTypes_default"
    ... />

Then, from the onCreate() method in your application's main activity—and in any other activity through which the user may enter your application for the first time—call setDefaultValues():

[译文:然后,在应用的主Activity的onCreate()方法中,以及任何其他用户可以直接进入你的应用的activity里,调用setDefaultValues()]

PreferenceManager.setDefaultValues(this, R.xml.advanced_preferences, false);

Calling this during onCreate() ensures that your application is properly initialized with default settings, which your application might need to read in order to determine some behaviors (such as whether to download data while on a cellular network).

[译文:在onCreate是调用这句,可以确保应用正确的使用缺省配置初始化。]

This method takes three arguments:

· Your application Context.

· The resource ID for the preference XML file for which you want to set the default values.

· A boolean indicating whether the default values should be set more than once.

When false, the system sets the default values only if this method has never been called in the past (or the KEY_HAS_SET_DEFAULT_VALUES in the default value shared preferences file is false).

[译文:这个方法有3个参数。1-应用的Context,2-XML文件的ResouceID,3-一个布尔值,指明是否可以多次设定缺省值。]

As long as you set the third argument to false, you can safely call this method every time your activity starts without overriding the user's saved preferences by resetting them to the defaults. However, if you set it to true, you will override any previous values with the defaults.

[译文:只要你设置第三个参数=false,你可以安全的调用这个(设置缺省值)方法,每次你的Activity启动时都可以,而不用担心会用缺省值覆盖用户已经更改的数据。如果是true,那就会用缺省值覆盖之前的所有数据]

Using Preference Headers

[使用Preference Headers]

 

In rare cases, you might want to design your settings such that the first screen displays only a list of subscreens (such as in the system Settings app, as shown in figures 4 and 5). When you're developing such a design for Android 3.0 and higher, you should use the "headers" feature instead of building subscreens with nested PreferenceScreen elements.

[译文:在少数情况下,你可能想要设计自己的配置,譬如第一屏就只显示低层屏幕的列表(如图4,5).如果你在Android3.0以上开发,应该使用Headers而不是嵌套的PreferenceScreen元素]

To build your settings with headers, you need to:

1. Separate each group of settings into separate instances of PreferenceFragment. That is, each group of settings needs a separate XML file.

2. Create an XML headers file that lists each settings group and declares which fragment contains the corresponding list of settings.

3. Extend the PreferenceActivity class to host your settings.

4. Implement the onBuildHeaders() callback to specify the headers file.

[译文:用Headers来创建配置,你需要:

1-把每组配置划分到PreferenceFragment。也就是说,每组Settings分别需要一个XML文件。

2-创建一个XML Headers文件,列出每组配置,并声明哪个Fragment包含着对应的配置项列表。

3-扩展PreferenceActivity来掌管你的配置;

4-实现onBuildHeaders()回调函数,来指定headers文件]

A great benefit to using this design is that PreferenceActivity automatically presents the two-pane layout shown in figure 4 when running on large screens.

[译文:一个很大的好处就是,使用这个设计,PreferenceActivity可以自动的在大尺寸屏幕呈现双区块布局,如图4所示]

Even if your application supports versions of Android older than 3.0, you can build your application to use PreferenceFragment for a two-pane presentation on newer devices while still supporting a traditional multi-screen hierarchy on older devices (see the section about Supporting older versions with preference headers).

[译文:即使你的应用要支持Android3.0更低的版本,也可以构建你的应用,使它在新设备上使用双区块呈现的PreferenceFragment,而在老设备上使用传统的多屏多层方式。参见‘在老设备上支持PreferenceHeaders’]

https://developer.android.com/images/ui/settings/settings-headers-tablet.png

Figure 4. Two-pane layout with headers.
1. The headers are defined with an XML headers file.
2. Each group of settings is defined by a PreferenceFragment that's specified by a <header> element in the headers file.

https://developer.android.com/images/ui/settings/settings-headers-handset.png

Figure 5. A handset device with setting headers. When an item is selected, the associated PreferenceFragment replaces the headers.

Creating the headers file

[译文:创建Headers文件]

Each group of settings in your list of headers is specified by a single <header> element inside a root <preference-headers> element. For example:

[译文:每一组‘配置项’,都要在根元素,preference-headers内,指定一个单独的header元素]

<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
    <header
        android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentOne"
        android:title="@string/prefs_category_one"
        android:summary="@string/prefs_summ_category_one" />
    <header
        android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentTwo"
        android:title="@string/prefs_category_two"
        android:summary="@string/prefs_summ_category_two" >
        <!-- key/value pairs can be included as arguments for the fragment. -->
        <extra android:name="someKey" android:value="someHeaderValue" />
    </header>
</preference-headers>

With the android:fragment attribute, each header declares an instance of PreferenceFragment that should open when the user selects the header.

[译文:利用android:fragment属性,每个header声明一个Preference Fragment的实例,这个实例将会在用户选择这个Header的时候打开。]

The <extras> element allows you to pass key-value pairs to the fragment in a Bundle. The fragment can retrieve the arguments by calling getArguments(). You might pass arguments to the fragment for a variety of reasons, but one good reason is to reuse the same subclass of PreferenceFragment for each group and use the argument to specify which preferences XML file the fragment should load.

[译文:元素extra允许你在一个Bundle里传递一个key-value对到fragment。Fragment可以用getArguments()来获得参数。传递参数的理由很多,一个很好的理由就是,复用相同的PreferenceFragment子类,并用参数指定应该加载哪个preferences XML文件]

For example, here's a fragment that can be reused for multiple settings groups, when each header defines an <extra> argument with the "settings" key:

[译文:例如,这里的fragment可以复用给多个‘配置项组’,而每个header使用extra参数定义 settings]

public static class SettingsFragment extends PreferenceFragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        String settings = getArguments().getString("settings");
        if ("notifications".equals(settings)) {
            addPreferencesFromResource(R.xml.settings_wifi);
        } else if ("sync".equals(settings)) {
            addPreferencesFromResource(R.xml.settings_sync);
        }
    }
}

Displaying the headers

[译文:显示Headers]

To display the preference headers, you must implement the onBuildHeaders() callback method and call loadHeadersFromResource(). For example:

[译文:要显示Preference Headers,你必须实现OnBuilHeaders回调方法,并调用LoadHeadersFromResource()]

public class SettingsActivity extends PreferenceActivity {
    @Override
    public void onBuildHeaders(List<Header> target) {
        loadHeadersFromResource(R.xml.preference_headers, target);
    }
}

When the user selects an item from the list of headers, the system opens the associated PreferenceFragment.

Note: When using preference headers, your subclass of PreferenceActivity doesn't need to implement the onCreate() method, because the only required task for the activity is to load the headers.

[译文:当用户选择一个Header条目时,系统会打开相关的PreferenceFragment。Note:在使用PreferenceHeaders时,你的PerferenceActivity子类不需要实现OnCreate方法,因为唯一必须的工作就是加载Headers]

Supporting older versions with preference headers

[译注:老版本支持的问题暂不关心,没翻译]

If your application supports versions of Android older than 3.0, you can still use headers to provide a two-pane layout when running on Android 3.0 and higher. All you need to do is create an additional preferences XML file that uses basic <Preference> elements that behave like the header items (to be used by the older Android versions).

Instead of opening a new PreferenceScreen, however, each of the <Preference> elements sends an Intent to the PreferenceActivity that specifies which preference XML file to load.

For example, here's an XML file for preference headers that is used on Android 3.0 and higher (res/xml/preference_headers.xml):

<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
    <header
        android:fragment="com.example.prefs.SettingsFragmentOne"
        android:title="@string/prefs_category_one"
        android:summary="@string/prefs_summ_category_one" />
    <header
        android:fragment="com.example.prefs.SettingsFragmentTwo"
        android:title="@string/prefs_category_two"
        android:summary="@string/prefs_summ_category_two" />
</preference-headers>

And here is a preference file that provides the same headers for versions older than Android 3.0 (res/xml/preference_headers_legacy.xml):

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <Preference
        android:title="@string/prefs_category_one"
        android:summary="@string/prefs_summ_category_one"  >
        <intent
            android:targetPackage="com.example.prefs"
            android:targetClass="com.example.prefs.SettingsActivity"
            android:action="com.example.prefs.PREFS_ONE" />
    </Preference>
    <Preference
        android:title="@string/prefs_category_two"
        android:summary="@string/prefs_summ_category_two" >
        <intent
            android:targetPackage="com.example.prefs"
            android:targetClass="com.example.prefs.SettingsActivity"
            android:action="com.example.prefs.PREFS_TWO" />
    </Preference>
</PreferenceScreen>

Because support for <preference-headers> was added in Android 3.0, the system calls onBuildHeaders() in your PreferenceActivity only when running on Android 3.0 or higher. In order to load the "legacy" headers file (preference_headers_legacy.xml), you must check the Android version and, if the version is older than Android 3.0 (HONEYCOMB), call addPreferencesFromResource() to load the legacy header file. For example:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
        // Load the legacy preferences headers
        addPreferencesFromResource(R.xml.preference_headers_legacy);
    }
}

// Called only on Honeycomb and later
@Override
public void onBuildHeaders(List<Header> target) {
   loadHeadersFromResource(R.xml.preference_headers, target);
}

The only thing left to do is handle the Intent that's passed into the activity to identify which preference file to load. So retrieve the intent's action and compare it to known action strings that you've used in the preference XML's <intent> tags:

final static String ACTION_PREFS_ONE = "com.example.prefs.PREFS_ONE";
...

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    String action = getIntent().getAction();
    if (action != null && action.equals(ACTION_PREFS_ONE)) {
        addPreferencesFromResource(R.xml.preferences);
    }
    ...

    else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
        // Load the legacy preferences headers
        addPreferencesFromResource(R.xml.preference_headers_legacy);
    }
}

Beware that consecutive calls to addPreferencesFromResource() will stack all the preferences in a single list, so be sure that it's only called once by chaining the conditions with else-if statements.

Reading Preferences

[译文:读取Preferences]

 

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.

[译文:默认情况下,所有的Preference都存在一个sharedPreference中,任何本应用内的模块都以调用PreferenceManager.getDefaultSharedPreferences()来获得它。它包含了所有你在PreferenceActivity里定义的Prefence相关的key-value对。]

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的变化]

There are several reasons you might want to be notified as soon as the user changes one of the preferences. In order to receive a callback when a change happens to any one of the preferences, implement the SharedPreference.OnSharedPreferenceChangeListener interface and register the listener for the SharedPreferences object by calling registerOnSharedPreferenceChangeListener().

[译文:有很多理由需要在用户改变preference时尽快通知你。为了在任何Preference改变发生后,可以收到一个回调,实现接口SharedPreference.OnSharedPreferenceChangeListener 并调用registerOnSharedPreferenceChangeListener()来注册SharedPReference的监听]

The interface has only one callback method, onSharedPreferenceChanged(), and you might find it easiest to implement the interface as a part of your activity. For example:

[译文:这个接口只有一个回调函数onSharedPReferenceChanged(). 最简单的方式是在你的Activity里实现这个接口]

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, ""));
        }
    }
}

In this example, the method checks whether the changed setting is for a known preference key. It calls findPreference() to get the Preference object that was changed so it can modify the item's summary to be a description of the user's selection. That is, when the setting is a ListPreference or other multiple choice setting, you should call setSummary() when the setting changes to display the current status (such as the Sleep setting shown in figure 5).

[译文:在这个例子里,函数检查这个改变是否针对一个已知的配置项的key。它调用findPreference来获得被改变的Preference对象,这样它就可以根据的用户的选择来改变条目显示的摘要。也就是,如果配置项是一个ListPreference,或其它多选配置项,你应该调用setSummary()来改变显示。]

Note: As described in the Android Design document about Settings, we recommend that you update the summary for a ListPreference each time the user changes the preference in order to describe the current setting.

[译文:建议每次用户更改了preference都更新Update]

For proper lifecycle management in the activity, we recommend that you register and unregister your SharedPreferences.OnSharedPreferenceChangeListener during the onResume() and onPause() callbacks, respectively:

[译文:为了Activity正确的生命周期管理,我们推荐在onResume和onPause里注册和注销监听]

@Override
protected void onResume() {
    super.onResume();
    getPreferenceScreen().getSharedPreferences()
            .registerOnSharedPreferenceChangeListener(this);
}

@Override
protected void onPause() {
    super.onPause();
    getPreferenceScreen().getSharedPreferences()
            .unregisterOnSharedPreferenceChangeListener(this);
}

Caution: 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.

[译文:注意:当你调用registerOnSharedPreferenceChangeListener()时,Preference管理器并没有持有一个对监听者的强引用。你必须自己保存一个监听器的引用,否则它就是GC可回收的。我们推荐在和监听器生存期相同的数据对象中保存 ]

For example, in the following code, the caller does not keep a reference to the listener. As a result, the listener will be subject to garbage collection, and it will fail at some indeterminate time in the future:

[译文:例如,下面代码中,调用者没有保存监听者的引用。结果,GC就会将其作为可回收的目标,因此它会在未来某个时间失效。]

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);

Managing Network Usage

[译文:管理网络使用情况]

 

Beginning with Android 4.0, the system's Settings application allows users to see how much network data their applications are using while in the foreground and background. Users can then disable the use of background data for individual apps. In order to avoid users disabling your app's access to data from the background, you should use the data connection efficiently and allow users to refine your app's data usage through your application settings.

[译文:从Andriod4.0开始,系统配置程序允许用户查看它的应用在前台和后台消费了多少网络数据。用户可以据此单独的关闭某个APP的后台数据访问。为了避免用户关闭你的APP的后台数据访问,你应该允许用户通过应用的配置项,来调整你的数据消费,有效的使用数据连接。]

For example, you might allow the user to control how often your app syncs data, whether your app performs uploads/downloads only when on Wi-Fi, whether your app uses data while roaming, etc. With these controls available to them, users are much less likely to disable your app's access to data when they approach the limits they set in the system Settings, because they can instead precisely control how much data your app uses.

[译文:例如,你会允许用户指定多久同步一次数据,或者你的APP仅在Wifi下上传和下载数据,或者在漫游时使用数据,等等。用户可以控制这些,他们就基本不会在达到他们指定的系统限额时,去关闭你的APP的数据访问。因为他们已可以精细的控制你的应用消耗多少数据流量]

Once you've added the necessary preferences in your PreferenceActivity to control your app's data habits, you should add an intent filter for ACTION_MANAGE_NETWORK_USAGE in your manifest file. For example:

[译文:一旦你在你的PreferenceActivity添加了必要的Preference来控制你的APP的数据行为,你可以在你的manifest文件中,添加一个ACTION_MANAGE_NETWORK_USAGE的IntentFilter ]

<activity android:name="SettingsActivity" ... >
    <intent-filter>
       <action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
       <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

This intent filter indicates to the system that this is the activity that controls your application's data usage. Thus, when the user inspects how much data your app is using from the system's Settings app, a View application settings button is available that launches your PreferenceActivity so the user can refine how much data your app uses.

[译文:这个intent filter给系统指示了,这个Activity控制你的应用的数据消费。因此,当用户在系统配置界面检查你的APP用了多少数据时,一个View Application Setting按钮就可用了,它可以把你的PreferenceActivity启动起来,这样用户就可以方便的调整你的APP的数据消耗]

Building a Custom Preference

[译文:创建自定义Preference]

 

The Android framework includes a variety of Preference subclasses that allow you to build a UI for several different types of settings. However, you might discover a setting you need for which there’s no built-in solution, such as a number picker or date picker. In such a case, you’ll need to create a custom preference by extending the Preference class or one of the other subclasses.

[译文:Android自带了很多Preference的子类实现,可以用来构建多种类型的配置界面。然而,你可能会发现某些配置无法使用内置的实现来完成。例如数字和日期选择。这时,你需要创建一个自定义的preference,方法是扩展Preference或其子类]

When you extend the Preference class, there are a few important things you need to do:

[译文:扩展Preference时,有几个很重要的事要做:]

· Specify the user interface that appears when the user selects the settings.

[译文:设定用户选择配置项时,展示的UI]

· Save the setting's value when appropriate.

[译文:在恰当的时候保存配置的值]

· Initialize the Preference with the current (or default) value when it comes into view.

[译文:在Preference要显示的时候,用当前或缺省值正确的初始化]

· Provide the default value when requested by the system.

[译文:在系统需要时,提供缺省值]

· If the Preference provides its own UI (such as a dialog), save and restore the state to handle lifecycle changes (such as when the user rotates the screen).

[译文:如果Preference自己提供了UI,例如一个对话框,保存并恢复它来处理生命周期变化,例如用户旋转了屏幕]

The following sections describe how to accomplish each of these tasks.

[译文:下面几章描述了如何完成每步工作]

Specifying the user interface

[译文:指定用户界面]

If you directly extend the Preference class, you need to implement onClick() to define the action that occurs when the user selects the item. However, most custom settings extend DialogPreference to show a dialog, which simplifies the procedure. When you extend DialogPreference, you must call setDialogLayoutResourcs() during in the class constructor to specify the layout for the dialog.

[译文:如果你是直接从Prefrence继承,你需要实现onClick()方法,来定义用户选择条目时的动作。不过大多数自定义配置都扩展自DialogPreference,来显示一个对话框,这样更简单。当你扩展DialogPreference,你必须在构造函数中调用setDialogLayoutResourcs()来指定对话框的布局]

For example, here's the constructor for a custom DialogPreference that declares the layout and specifies the text for the default positive and negative dialog buttons:

[译文:例如,这里是一个自定义的DialogPreference的构造函数,声明了缺省布局,指定了正反选择按钮的文本]

public class NumberPickerPreference extends DialogPreference {
    public NumberPickerPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
       
        setDialogLayoutResource(R.layout.numberpicker_dialog);
        setPositiveButtonText(android.R.string.ok);
        setNegativeButtonText(android.R.string.cancel);
       
        setDialogIcon(null);
    }
    ...
}

Saving the setting's value

[译文:保存配置项的值]

You can save a value for the setting at any time by calling one of the Preference class's persist*() methods, such as persistInt() if the setting's value is an integer or persistBoolean() to save a boolean.

[译文:你可以在任何时候来保存配置值,只要调用Prefrence的persist*()方法就好。例如PersistInt(),persistBoolean()]

Note: Each Preference can save only one data type, so you must use the persist*() method appropriate for the data type used by your custom Preference.

[译文:Note:每个Preference只能保存一种数据类型,所以你必须使用正确类型的persist*()方法]

When you choose to persist the setting can depend on which Preference class you extend. If you extend DialogPreference, then you should persist the value only when the dialog closes due to a positive result (the user selects the "OK" button).

[译文: 选择在何时持久化配置项,取决于你扩展了哪种Preference。如果扩展了DialogPreference,你应该只在用户选择了肯定的结果,关闭对话框时保存(用户点击OK按钮)]

When a DialogPreference closes, the system calls the onDialogClosed() method. The method includes a boolean argument that specifies whether the user result is "positive"—if the value is true, then the user selected the positive button and you should save the new value. For example:

[译文:当DialogPreference关闭时,系统调用onDialogClosed()方法。这个方法包含了一个布尔型参数,指明了用户的结果是肯定的--值为true,那就表示用户选择了‘确定’的按钮,而你则应该保存新的值。]

@Override
protected void onDialogClosed(boolean positiveResult) {
    // When the user selects "OK", persist the new value
    if (positiveResult) {
        persistInt(mNewValue);
    }
}

In this example, mNewValue is a class member that holds the setting's current value. Calling persistInt() saves the value to the SharedPreferences file (automatically using the key that's specified in the XML file for this Preference).

[译文:本例中,mNewValue是一个类成员,保存着配置的当前值。调用persistInt()就把这个值存到SharedPReferences文件中了。(自动的使用XML中Preference配置的Key)]

Initializing the current value

[译文:初始化当前值]

When the system adds your Preference to the screen, it calls onSetInitialValue() to notify you whether the setting has a persisted value. If there is no persisted value, this call provides you the default value.

[译文:当系统将你的Preference加入到屏幕上,会调用onSetInitialValue来通知你这个配置项是否有一个已保存的值,如果没有,则提供一个缺省值。]

The onSetInitialValue() method passes a boolean, restorePersistedValue, to indicate whether a value has already been persisted for the setting. If it is true, then you should retrieve the persisted value by calling one of the Preference class's getPersisted*() methods, such as getPersistedInt() for an integer value. You'll usually want to retrieve the persisted value so you can properly update the UI to reflect the previously saved value.

[译文:onSetInitialValue方法传递一个布尔参数restorePersistedValue,来指明这个配置项是否已经持久化了。为True,你就应该调用Perference的getPersisted*()方法来获取已有的值。通常你都要取已有的值来正确的刷新界面]

If restorePersistedValue is false, then you should use the default value that is passed in the second argument.

[译文:如果为False,则你应该使用第二个参数传递的缺省值]

@Override
protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
    if (restorePersistedValue) {
        // Restore existing state
        mCurrentValue = this.getPersistedInt(DEFAULT_VALUE);
    } else {
        // Set default state from the XML attribute
        mCurrentValue = (Integer) defaultValue;
        persistInt(mCurrentValue);
    }
}

Each getPersisted*() method takes an argument that specifies the default value to use in case there is actually no persisted value or the key does not exist. In the example above, a local constant is used to specify the default value in case getPersistedInt() can't return a persisted value.

[译文:每个getPersisted*()方法都有一个缺省值参数,以防实际上并没有对应的配置项值。上例中,一个本地常量用来指定缺省值。]

Caution: You cannot use the defaultValue as the default value in the getPersisted*() method, because its value is always null when restorePersistedValue is true.

[译文:警告:你不能使用defaultValue作为缺省值,因为在restorePersistedValue为true时,它总是null]

Providing a default value

[译文:提供缺省值]

If the instance of your Preference class specifies a default value (with the android:defaultValue attribute), then the system calls onGetDefaultValue() when it instantiates the object in order to retrieve the value. You must implement this method in order for the system to save the default value in the SharedPreferences. For example:

[译文:如果你的Preference实现指定了一个缺省值(android:defaultValue属性),系统会在实例化对象时调用onGetDefaultValue()。你必须实现这个方法,让系统可以把缺省值保存到SharedPreferences]

@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
    return a.getInteger(index, DEFAULT_VALUE);
}

The method arguments provide everything you need: the array of attributes and the index position of the android:defaultValue, which you must retrieve. The reason you must implement this method to extract the default value from the attribute is because you must specify a local default value for the attribute in case the value is undefined.

[译文:这个方法的参数提供了你需要的所有信息:属性数组和缺省值的(必须的)位置索引。你必须实现这个方法的原因是,你必须指定一个本地缺省值以防这个值是未定义的(空值,无效值等)]

Saving and restoring the Preference's state

[译文:保存恢复Preference的状态]

Just like a View in a layout, your Preference subclass is responsible for saving and restoring its state in case the activity or fragment is restarted (such as when the user rotates the screen). To properly save and restore the state of your Preference class, you must implement the lifecycle callback methods onSaveInstanceState() and onRestoreInstanceState().

[译文:就如布局中的View一样,你的Preference子类实现负责在应用或者fragment重启时保存和恢复它的状态(例如旋转了屏幕)。为了正确的保存和恢复你的Preference状态,你必须实现生命周期回调函数onSaveInstanceState()和onRestoreInstanceState()]

The state of your Preference is defined by an object that implements the Parcelable interface. The Android framework provides such an object for you as a starting point to define your state object: the Preference.BaseSavedState class.

[译文:你的Preference状态是由一个实现了Parcelable接口的对象定义。Android提供了一个让你自定义状态的起点:Preference.BaseSavedState类]

To define how your Preference class saves its state, you should extend the Preference.BaseSavedState class. You need to override just a few methods and define the CREATOR object.

[译文:要定义如何保存Preference的状态,需要扩展Preference.BaseSavedState类。 值需要复写几个方法,再定义一下CREATOR对象就可以了]

For most apps, you can copy the following implementation and simply change the lines that handle the value if your Preference subclass saves a data type other than an integer.

[译文:大多数APP可以拷贝下面的实现,简单的修改几行代码来处理value,如果你的数据类型不是Integer的话]

private static class SavedState extends BaseSavedState {
    // Member that holds the setting's value
    // Change this data type to match the type saved by your Preference
    int value;

    public SavedState(Parcelable superState) {
        super(superState);
    }

    public SavedState(Parcel source) {
        super(source);
        // Get the current preference's value
        value = source.readInt();  // Change this to read the appropriate data type
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        // Write the preference's value
        dest.writeInt(value);  // Change this to write the appropriate data type
    }

    // Standard creator object using an instance of this class
    public static final Parcelable.Creator<SavedState> CREATOR =
            new Parcelable.Creator<SavedState>() {

        public SavedState createFromParcel(Parcel in) {
            return new SavedState(in);
        }

        public SavedState[] newArray(int size) {
            return new SavedState[size];
        }
    };
}

With the above implementation of Preference.BaseSavedState added to your app (usually as a subclass of your Preference subclass), you then need to implement the onSaveInstanceState() and onRestoreInstanceState() methods for your Preference subclass.

[译文:把上面的实行加到你的APP里(通常是作为你的Preference子类实现的子类),然后你需要实现onSaveInstanceState和onRestoreInstanceState方法]

For example:

@Override
protected Parcelable onSaveInstanceState() {
    final Parcelable superState = super.onSaveInstanceState();
    // Check whether this Preference is persistent (continually saved)
    if (isPersistent()) {
        // No need to save instance state since it's persistent,
        // use superclass state
        return superState;
    }

    // Create instance of custom BaseSavedState
    final SavedState myState = new SavedState(superState);
    // Set the state's value with the class member that holds current
    // setting value
    myState.value = mNewValue;
    return myState;
}

@Override
protected void onRestoreInstanceState(Parcelable state) {
    // Check whether we saved the state in onSaveInstanceState
    if (state == null || !state.getClass().equals(SavedState.class)) {
        // Didn't save the state, so call superclass
        super.onRestoreInstanceState(state);
        return;
    }

    // Cast state to custom BaseSavedState and pass to superclass
    SavedState myState = (SavedState) state;
    super.onRestoreInstanceState(myState.getSuperState());
   
    // Set this Preference's widget to reflect the restored state
    mNumberPicker.setValue(myState.value);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值