android.preference

此包下的类主要以Preference为父类,PreferenceActivity继承自ListActivity用来显示UI,以ListView形式显示,preference主要用来做配置文件,所做的选择以Sharedpreference(xml)形式存于程序目录下。

使用方式:定义一个xml(随便放哪,最好在res下建个xml文件夹,放里面)文件,在java代码中addPreferencesFromResource(int res),最基本的preference就完成了。

xml文件内以PreferenceScreen作为根节点,比如:

[html]  view plain copy
  1. <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">  
  2.     <ListPreference android:entryValues="@array/r"   
  3.         android:entries="@array/r"   
  4.         android:title="qqqqqqqq"  
  5.          android:summary="wwwwwwwwww"   
  6.          android:dialogTitle="hhh" android:key="55"/>  
  7.     <CheckBoxPreference />  
  8. </PreferenceScreen>  

Preference :所有preference的父类,其属性子类继承

XML属性:

android:key   用于存储、取出数据的key。

android:title   用于显示的标题,标题在上面一行,最多有两行。

android:summary   摘要,配置的简要说明,显示在标题下面

android:selectable  是否能点取选择,设置false则此条preference不可选(lose focus)

android:enabled    是否起作用,false则能点取,但是不作用(有焦点)

android:shouldDisableView   当enabled设置为false,此属性设置为true时,preference所代表的item变暗

android:layout    自定义item的View


DialogPreference:弹dialog的preference的父类,不直接在XML文件中定义,而用其子类。继承自Preference 

android:dialogIcon    弹出的dialog的图标

android:dialogMessage  dialog的消息

android:dialogTitle     dialog的标题

android:negativeButtonText   dialog的取消按钮上面的文字

android:positiveButtonText    dialog的确定按钮上的文字

android:dialogLayout     自定义dialog布局


ListPreference:点击后弹dialog,dialog内是个单选ListView。继承自DialogPreference

XML属性:

android:entries   用于显示的数组,弹出来的Dialog中ListView所显示的内容

android:entryValues  被选取后所得到的数据,数组,对应entries。

不能设置dialogMessage,否则ListView将被Message内容覆盖。


EditTextPreference:点击后弹dialog,dialog的View部分是个EditText。继承自DialogPreference

XML属性:没有独有属性


TwoStatePreference:代表两种状态转换的配置类,不直接用,而用其子类

XML属性:没有独有属性


CheckBoxPreference: 带checkbox的item,点击后checkbox状态改变。4.0继承自TwoStatePreference,2.3继承自Preference

XML属性:

android:summaryOff  当checkbox状态为false时,显示的摘要内容

android:summaryOn  当checkbox状态为true时,显示的摘要内容


PreferenceCategory:对preference进行分组。

XML属性:没有独有属性

android.preference_第1张图片




源码分析:

当点击Preference的Item时,首先触发方法:performClick(PreferenceScreen preferenceScreen) 

[java]  view plain copy
  1. void performClick(PreferenceScreen preferenceScreen) {  
  2.       
  3.     if (!isEnabled()) {  
  4.         return;  
  5.     }  
  6.       
  7.     onClick();  
  8.       
  9.     if (mOnClickListener != null && mOnClickListener.onPreferenceClick(this)) {  
  10.         return;  
  11.     }  
  12.       
  13.     PreferenceManager preferenceManager = getPreferenceManager();  
  14.     if (preferenceManager != null) {  
  15.         PreferenceManager.OnPreferenceTreeClickListener listener = preferenceManager  
  16.                 .getOnPreferenceTreeClickListener();  
  17.         if (preferenceScreen != null && listener != null  
  18.                 && listener.onPreferenceTreeClick(preferenceScreen, this)) {  
  19.             return;  
  20.         }  
  21.     }  
  22.       
  23.     if (mIntent != null) {  
  24.         Context context = getContext();  
  25.         context.startActivity(mIntent);  
  26.     }  
  27. }  
很明显,如果设置了setEnable(false),后面所有代码都失去作用了。


onClick()是个protect的空方法,留给子类用的。下面的这一段代码决定了监听事件的响应,如果设置了监听,那么点击时调用监听事件得到返回值,如果返回true,则后面的代码不执行了,false则继续执行。
[java]  view plain copy
  1. if (mOnClickListener != null && mOnClickListener.onPreferenceClick(this)) {  
  2.     return;  
  3. }  
下面一段代码决定了点击后跳转到另一个Activity。
[java]  view plain copy
  1. if (mIntent != null) {  
  2.     Context context = getContext();  
  3.     context.startActivity(mIntent);  
  4. }  
其中mIntent可通过setIntent(Intent intent)方法设定,也可在布局文件中如下设定
[html]  view plain copy
  1. <Preference android:title="@string/ua_settings" >  
  2.   
  3.     <intent  
  4.         android:action="android.intent.action.webview"  
  5.         android:targetClass="com.yeezone.engtest.Uaagent"  
  6.         android:targetPackage="com.yeezone.engtest" />  
  7. </Preference>  

源码版本2.3:

CheckboxPreference:

实现父类Preference的onclick方法:

[java]  view plain copy
  1. @Override  
  2. protected void onClick() {  
  3.     super.onClick();  
  4.       
  5.     boolean newValue = !isChecked();  
  6.       
  7.     // in onBindView() an AccessibilityEventViewClickedType is sent to announce the change  
  8.     // not sending  
  9.     mSendAccessibilityEventViewClickedType = true;  
  10.   
  11.     if (!callChangeListener(newValue)) {  
  12.         return;  
  13.     }  
  14.       
  15.     setChecked(newValue);  
  16. }  
其中callChangeListener(newValue)方法代码如下:
[java]  view plain copy
  1. protected boolean callChangeListener(Object newValue) {  
  2.     return mOnChangeListener == null ? true : mOnChangeListener.onPreferenceChange(this, newValue);  
  3. }  
上面这个方法中可以看出,如果对这个Preference进行了Preference.OnPreferenceChangeListener监听,并且监听的返回值为true那么后面的代码将不会再执行。

setChecked(newValue)方法会把newValue存到配置文件中去。


DialogPreference:不直接使用,而是作为父类使用

实现父类Preference的onclick方法:

[java]  view plain copy
  1. @Override  
  2. protected void onClick() {  
  3.     showDialog(null);  
  4. }  
其中showDialog方法主要用来构建并显示一个AlertDialog,并且调用onPrepareDialogBuilder(mBuilder);方法,并且对Dialog实现dissmiss监听,在onDismiss方法中调用方法onDialogClosed(mWhichButtonClicked == DialogInterface.BUTTON_POSITIVE);,onPrepareDialogBuilder与onDialogClosed是空方法,留给子类实现。showDialog代码如下:
[java]  view plain copy
  1. protected void showDialog(Bundle state) {  
  2.        Context context = getContext();  
  3.   
  4.        mWhichButtonClicked = DialogInterface.BUTTON_NEGATIVE;  
  5.          
  6.        mBuilder = new AlertDialog.Builder(context)  
  7.            .setTitle(mDialogTitle)  
  8.            .setIcon(mDialogIcon)  
  9.            .setPositiveButton(mPositiveButtonText, this)  
  10.            .setNegativeButton(mNegativeButtonText, this);  
  11.   
  12.        View contentView = onCreateDialogView();  
  13.        if (contentView != null) {  
  14.            onBindDialogView(contentView);  
  15.            mBuilder.setView(contentView);  
  16.        } else {  
  17.            mBuilder.setMessage(mDialogMessage);  
  18.        }  
  19.          
  20.        onPrepareDialogBuilder(mBuilder);  
  21.          
  22.        getPreferenceManager().registerOnActivityDestroyListener(this);  
  23.          
  24.        // Create the dialog  
  25.        final Dialog dialog = mDialog = mBuilder.create();  
  26.        if (state != null) {  
  27.            dialog.onRestoreInstanceState(state);  
  28.        }  
  29.        if (needInputMethod()) {  
  30.            requestInputMethod(dialog);  
  31.        }  
  32.        dialog.setOnDismissListener(this);  
  33.        dialog.show();  
  34.    }  
从上面代码中可以看出,如果 View contentView = onCreateDialogView();得到的contentView 是个null则Dialog为一个简短消息的Dialog,不为null还是个简短消息的Dialog,不过样式不同了。可继承DialogPreference,重写onCreateDialogView()方法来达到控制Dialog显示的目的。
[java]  view plain copy
  1. protected View onCreateDialogView() {  
  2.     if (mDialogLayoutResId == 0) {  
  3.         return null;  
  4.     }  
  5.       
  6.     LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(  
  7.             Context.LAYOUT_INFLATER_SERVICE);  
  8.     return inflater.inflate(mDialogLayoutResId, null);  
  9. }  


EditTextPreference:继承DialogPreference

重写了onPrepareDialogBuilder(mBuilder)方法,把Dialog的View部分变成了一个EditText。没有从写onPrepareDialogBuilder(mBuilder)方法,重写了onDialogClosed方法,代码如下:

[java]  view plain copy
  1. @Override  
  2. protected void onDialogClosed(boolean positiveResult) {  
  3.     super.onDialogClosed(positiveResult);  
  4.       
  5.     if (positiveResult) {  
  6.         String value = mEditText.getText().toString();  
  7.         if (callChangeListener(value)) {  
  8.             setText(value);  
  9.         }  
  10.     }  
  11. }  
从上面的代码可以看出,此方法被调时,如果参数 是true并且callChangeListener(value)返回true,则保存变化的值到配置文件中,当且仅当点击了确定按钮时才会传true。callChangeListener方法说明在CheckboxPreference部分。


ListPreference:继承DialogPreference

重写了onPrepareDialogBuilder与onDialogClosed方法,onPrepareDialogBuilder代码如下:

[java]  view plain copy
  1. @Override  
  2.    protected void onPrepareDialogBuilder(Builder builder) {  
  3.        super.onPrepareDialogBuilder(builder);  
  4.          
  5.        if (mEntries == null || mEntryValues == null) {  
  6.            throw new IllegalStateException(  
  7.                    "ListPreference requires an entries array and an entryValues array.");  
  8.        }  
  9.   
  10.        mClickedDialogEntryIndex = getValueIndex();  
  11.        builder.setSingleChoiceItems(mEntries, mClickedDialogEntryIndex,   
  12.                new DialogInterface.OnClickListener() {  
  13.                    public void onClick(DialogInterface dialog, int which) {  
  14.                        mClickedDialogEntryIndex = which;  
  15.   
  16.                        /* 
  17.                         * Clicking on an item simulates the positive button 
  18.                         * click, and dismisses the dialog. 
  19.                         */  
  20.                        ListPreference.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE);  
  21.                        dialog.dismiss();  
  22.                    }  
  23.        });  
  24.          
  25.        /* 
  26.         * The typical interaction for list-based dialogs is to have 
  27.         * click-on-an-item dismiss the dialog instead of the user having to 
  28.         * press 'Ok'. 
  29.         */  
  30.        builder.setPositiveButton(nullnull);  
  31.    }  
代码比较容易懂。

onDialogClosed代码如下:

[java]  view plain copy
  1. @Override  
  2.    protected void onDialogClosed(boolean positiveResult) {  
  3.        super.onDialogClosed(positiveResult);  
  4.          
  5.        if (positiveResult && mClickedDialogEntryIndex >= 0 && mEntryValues != null) {  
  6.            String value = mEntryValues[mClickedDialogEntryIndex].toString();  
  7.            if (callChangeListener(value)) {  
  8.                setValue(value);  
  9.            }  
  10.        }  
  11.    }  

原理参见前面解释。

你可能感兴趣的:(android.preference)