您的位置:首页 > 移动开发 > Android开发

android学习日记——PreferenceActivity详解

2014-10-21 15:11 471 查看

PreferenceActivity详解

何为PreferenceActivity

以下为官方解释:

This is the base class for anactivity to show a hierarchy of preferences to the user. 

个人理解:这是一个特别针对Android开发中经常用到的选项设置而封装的Activity。

 

几点注意的:

l  官方推荐跟PreferenceFragment结合使用,继承该类的子类重写onBuildHeaders(List)方法来填充首选项的值,以header + PreferenceFragment的方式取代以前直接显示选项表的做法。

l  该Activity应包含一个或多个选项头(header),且每一个选项头对应一个PreferenceFragment,但与其关联的布局显示可以完全不同

l  针对不同尺寸,页面显示效果不同。针对大屏幕,同一页面中选项头与PreferenceFragment同时显示;针对小屏幕,同一页面中,只有选项头以列表的形式显示,PreferenceFragment以下一级页面显示。

l  依据官方推荐的办法,在一个Header的情况下小屏幕设备上有多页面的效果,显得有点多余,如果想直接就显示选项,有两种办法:

1.        直接在PreferenceActivity调用addPreferencesFromResource方法

2.        Android 3.0 之后推荐使用PreferenceFragment。具体办法为在Activity页面中定义一个PreferenceFragment并在重写的onCreate办法中加载其布局文件,在该Activity页面中的onCreate办法添加PreferenceFragment。(PS:核心代码:getFragmentManager().beginTransaction().replace(android.R.id.content,new
XXXFragment()).commit();)

 

 

例子

官方例子主要文件:

l  Java源文件PreferenceWithHeaders;

l  首选项xml布局文件 preference_headers;

l  次级选项PreferenceFragment的xml布局文件fragmented_preferences;fragmented_preferences_inner等等。

简单说下官方例子的编程思路:

1.        新建一个X.java文件继承PreferenceActivity,重写onBuildHeaders(List<Header>target),在里面调用loadHeadersFromResource (int resid,List<PreferenceActivity.Header>
target)办法填充首选项列表

2.        新建一个首选项列表的布局文件preference_headers .xml

3.        在x.java类里加入与布局文件中相应headers关联的PreferenceFragment子类为内部类,在子类里重写onCreate方法,加载此PreferenceFragment的布局文件

4.        新建一个与刚PreferenceFragment相关联的布局文件

5.        重复3,4步骤直到完成所需

 

扩展

l  自定义Preference(引用,不详)

有5点需要注意的,官方文档如下显示

·        Specify the user interface that appears when the userselects the settings.
·        Save the setting's value when appropriate.
·        Initialize the Preference with
thecurrent (or default) value when it comes into view.
·        Provide the default value when requested by the system.
·        If the Preference providesits
own UI (such as a dialog), save and restore the state to handle lifecyclechanges (such as when the user rotates the screen).
·        The following sections describehow to accomplish each of these tasks.

·        Specifying the user interface

·         
·        If you directly extendthe Preference class,you
need to implement onClick() todefine the action that occurs
when the user selects the item. However, mostcustom settings extend DialogPreference toshow
a dialog, which simplifies the procedure. When you extend DialogPreference,you
must callsetDialogLayoutResourcs() duringin
the class constructor to specify the layout for the dialog.
·        For example, here's theconstructor for a custom DialogPreference thatdeclares
the layout and specifies the text for the default positive andnegative dialog buttons:

·    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(andro
4000
id.R.string.cancel);

·          

·          setDialogIcon(null);

·       }

·       ...

·    }


·        Saving the setting's value

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

·        Note: Each Preference cansave
only one data type, so you must use the 
persist*()
 methodappropriate for the data type used by your custom Preference.

·        When you choose to persist thesetting can depend on which Preference classyou
extend. If you extendDialogPreference,then you should persist
the value only when the dialog closes due to a positiveresult (the user selects the "OK" button).
·        When a DialogPreference closes,the
system calls the onDialogClosed() method.The
method includes a boolean argument that specifies whether the user resultis "positive"—if the value is 
true
, thenthe user selected the positive button and you should save the
new value. Forexample:

·    @Override

·    protected void onDialogClosed(boolean positiveResult) {

·       // When the user selects "OK", persist the new value

·       if (positiveResult) {

·          persistInt(mNewValue);

·       }

·    }


·        Initializing the current value

·        When the system adds your Preference tothe
screen, it calls onSetInitialValue() tonotify
you whether the setting has a persisted value. If there is no persistedvalue, this call provides you the default value.
·        The onSetInitialValue() methodpasses
a boolean, 
restorePersistedValue
, toindicate whether a value has already been persisted for the setting. If itis 
true
,then
you should retrieve the persisted value by calling one of the Preference class's 
getPersisted*()
 methods,such
as getPersistedInt() foran integer value. You'll
usually want to retrieve the persisted value so youcan properly update the UI to reflect the previously saved value.
·        If 
restorePersistedValue
 is 
false
,then
you should use the default value that is passed in the second argument.

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

·       }

·    }


·        Providing a default value

·        If the instance of your Preference classspecifies
a default value (with the 
android:defaultValue
 attribute),then the system calls onGetDefaultValue() whenit
instantiates the object in order to retrieve the value. You must implementthis method in order for the system to save the default value in the SharedPreferences.For
example:

·    @Override

·    protected Object onGetDefaultValue(TypedArray a, int index) {

·       return a.getInteger(index, DEFAULT_VALUE);

·    }


·        Saving and restoring the Preference's state

·        Just like a View ina
layout, your Preference subclassis responsible for saving and restoring
its state in case the activity orfragment is restarted (such as when the user rotates the screen). To properlysave and restore the state of your Preference class,you
must implement the lifecycle callback methods onSaveInstanceState()and onRestoreInstanceState().
·        The state of your Preference isdefined
by an object that implements the Parcelable interface.The Android framework
provides such an object for you as a starting point todefine your state object: thePreference.BaseSavedState class.

·    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
107ca
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 implementationof Preference.BaseSavedState addedto
your app (usually as a subclass of your Preference subclass),you then
need to implement the onSaveInstanceState() andonRestoreInstanceState() methodsfor
your Preference subclass.
·        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);

·    }

·    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 implementationof Preference.BaseSavedState addedto
your app (usually as a subclass of your Preference subclass),you then
need to implement the onSaveInstanceState() andonRestoreInstanceState() methodsfor
your Preference subclass.
 
 

 

l  使用intents跳转其他页面:如网页

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

l  读取数据

取得该页面的SharedPreferences对象来读取数据,如下所示

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);

String syncConnPref = sharedPref.getString(SettingsActivity.KEY_PREF_SYNC_CONN, "");


l  监听preference 变化

通过将PreferenceActivity的子类实现SharedPreference.OnSharedPreferenceChangeListener接口,实现onSharedPreferenceChanged()办法。官方推荐重写PreferenceActivity的暂停和重新开始的办法,调用registerOnSharedPreferenceChangeListener()为SharedPreferences对象注册监听器实现监听,如下

protected void onResume() {

    super.onResume();

    getPreferenceScreen().getSharedPreferences()

            .registerOnSharedPreferenceChangeListener(this);

}


l  引用(不详)

从Android4.0以后,系统设置应用程序允许用户查看他们的应用在前台和后台使用了多少网络数据。用户可以禁用每个应用在后台使用网络数据。为了避免用户禁用你的应用在后台访问网络,你应该更效率的使用网络,并且允许用户通过你的应用的Settings来改善数据用量。

例如,你或许允许用户控制你的应用同步数据的频率,是否你的app只在wifi下上传下载数据,是否在漫游时访问网络等。

当你添加了必要的Preference到你的PreferenceActivity中来控制你的app的数据访问习惯,你应该添加一个Intent filter给你的PreferenceActivity。例子:

<activityandroid:name="SettingsActivity" ... >

   <intent-filter>

      <actionandroid:name="android.intent.action.MANAGE_NETWORK_USAGE" />

      <category android:name="android.intent.category.DEFAULT"/>

   </intent-filter>

</activity>

这个Intent-filter告诉系统这个Activity是控制你的应用程序的数据用量的Activity。因此,当用户从系统设置应用程序中查询你的应用使用了多少数据时,一个查看”应用程序设置“的按钮就可以加载你的PreferenceActivity,用户也就可以改善你的应用应该如何使用数据。

 

参考:http://supershll.blog.163.com/blog/static/37070436201311931338135/

官方文档;     






内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息