OnPreferenceChangeListener與OnPreferenceClickListener的分析

 最近學習Android中PreferenceScreen的時候,遇到兩種監聽器OnPreferenceChangeListener和OnPreferenceClickListener,OnPreferenceClickListener的意思好理解,但是OnPreferenceChangeListener就不好懂了,所以就寫了個Demo分析了一下,代碼如下:

複製代碼
 1 package com.luther.test;
2
3 import com.luther.test.R;
4
5 import android.content.SharedPreferences;
6 import android.os.Bundle;
7 import android.preference.CheckBoxPreference;
8 import android.preference.EditTextPreference;
9 import android.preference.ListPreference;
10 import android.preference.Preference;
11 import android.preference.Preference.OnPreferenceChangeListener;
12 import android.preference.Preference.OnPreferenceClickListener;
13 import android.preference.PreferenceActivity;
14 import android.preference.PreferenceManager;
15 import android.preference.PreferenceScreen;
16 import android.widget.Toast;
17
18 public class PreferenceDemoActivity extends PreferenceActivity
19 implements OnPreferenceChangeListener, OnPreferenceClickListener{
20
21 private ListPreference mList1Prefs;
22 private ListPreference mList2Prefs;
23 private CheckBoxPreference mCheckPrefs;
24 private EditTextPreference mEditPrefs;
25 private SharedPreferences mSharedPrefs;
26
27 /** Called when the activity is first created. */
28 @Override
29 public void onCreate(Bundle savedInstanceState) {
30 super.onCreate(savedInstanceState);
31 addPreferencesFromResource(R.xml.preference);
32 initViews();
33 }
34
35 private void initViews(){
36 //得到以包命名的SharedPreferences
37 mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);

38
39 mList1Prefs = (ListPreference) findPreference("key_call_config");
40 mList2Prefs = (ListPreference) findPreference("key_msg_config");
41 mCheckPrefs = (CheckBoxPreference) findPreference("switch");
42 mEditPrefs = (EditTextPreference) findPreference("autoreply_text_cpntent");
43
44 mList1Prefs.setOnPreferenceClickListener(this);
45 mList1Prefs.setOnPreferenceChangeListener(this);
46 mList2Prefs.setOnPreferenceChangeListener(this);
47 mList2Prefs.setOnPreferenceClickListener(this);
48 }
49
50 @Override
51 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
52 Preference preference) {
53 if(preference == mEditPrefs){
54 String toastStr = mEditPrefs.getTitle() + "\n"
55 + "Content: " + mEditPrefs.getText();
56 showToast(toastStr);
57 }
58 return super.onPreferenceTreeClick(preferenceScreen, preference);
59 }
60
61 public boolean onPreferenceClick(Preference preference) {
62 String prefsValue = mSharedPrefs.getString(preference.getKey(), "-1");
63 showToast(prefsValue);
64 return false;
65 }
66
67 public boolean onPreferenceChange(Preference preference, Object newValue) {
68
69 if(mList1Prefs == preference){
70 String prefsValue = mSharedPrefs.getString(preference.getKey(), "-1");
71 showToast(prefsValue);
72 }
73 if(mList2Prefs == preference){
74 String prefsValue = newValue.toString();
75 showToast(prefsValue);
76 mList2Prefs.setValue(prefsValue);
77 }
78 return false;
79 }
80
81 private void showToast(String arg){
82 Toast.makeText(this, arg, Toast.LENGTH_SHORT).show();
83 }
84
85 }
複製代碼

程序原理:用一個ListPreference分別註冊這兩個監聽器,然後用Tosat看他們在什麼時候響應。

.../res/xml/preference文件如下:

複製代碼
 1 <?xml version="1.0" encoding="utf-8"?>
2 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
3 android:title="@string/settings">

4 <PreferenceCategory
5     android:title="@string/general_settings">

6 <ListPreference
7        android:key="key_call_config"
8 android:title="@string/incoming_call_come"
9 android:dialogTitle="@string/incoming_call_come"
10 android:entries="@array/response_entries"
11 android:entryValues="@array/response_entry_values"/>

12 <ListPreference
13        android:key="key_msg_config"
14 android:title="@string/message_come"
15 android:dialogTitle="@string/message_come"
16 android:entries="@array/response_entries"
17 android:entryValues="@array/response_entry_values"/>

18 </PreferenceCategory>
19
20 <PreferenceCategory
21      android:title="@string/user_defined_autoreply_settings">

22 <CheckBoxPreference
23        android:title="@string/autoreply_switch"
24 android:key="switch"/>

25 <EditTextPreference
26        android:title="@string/user_defined_autoreply_text"
27 android:key="autoreply_text_cpntent"
28 android:dependency="switch"
29 android:dialogTitle="@string/user_defined_autoreply_text"
30 android:positiveButtonText="@android:string/ok"
31 android:negativeButtonText="@android:string/cancel"/>

33 </PreferenceCategory>
34
35 </PreferenceScreen>
複製代碼

以下是ListPreference的Entries和EntryValues:

複製代碼
 1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3 <string-array name="response_entries">
4 <item>靜音</item>
5 <item>振動</item>
6 <item>正常響鈴</item>
7 <item>LED燈亮</item>
8 </string-array>
9 <string-array name="response_entry_values">
10 <item>0</item>
11 <item>1</item>
12 <item>2</item>
13 <item>3</item>
14 </string-array>
15
16 </resources>
複製代碼

string.xml文件: 

複製代碼
 1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3 <string name="hello">Hello World, PreferenceDemoActivity!</string>
4 <string name="app_name">PreferenceDemo</string>
5 <string name="settings">設置</string>
6
7 <string name="general_settings">常規設置</string>
8 <string name="incoming_call_come">來電時</string>
9 <string name="message_come">來短信時</string>
10
11
12 <string name="user_defined_autoreply_settings">自定義回覆設置</string>
13 <string name="autoreply_switch">自動回覆</string>
14 <string name="user_defined_autoreply_text">自動回覆短信</string>
15 </resources>
複製代碼

 

下面是Demo的主界面:


編譯好,運行程序:點擊mList1Prefs(來電時),Toast顯示“-1”。再點擊一個選項,對話框消失,Toast顯示“-1”,爲什麼會這樣?爲什麼不是第一次選中時的選項值?

其實,這是因爲設置了OnPreferenceChangeListener。默認情況下,普通的ListPreference第一次選中一個值之後,Android框架會存貯好選中的值,下次打開,會默認選中上次選中的值,但是設置OnPreferenceChangeListener之後,值的存儲就要自己來了,詳見代碼中的mList2Prefs.setValue();“來短信時”這一項就能夠正常存貯選中的值。

現在區別就出來了:

OnPreferenceClickListener:是響應點擊preference的事件,比如程序中,一點ListPreference,onPreferenceClick()中就彈出Toast。

OnPreferenceChangeListener:是響應preference的值被改變的事件(此時被改變的值需要自己存貯到SharedPreferences) ,比如程序中,點擊ListPreference的某一項,onPreferenceChange()中就會彈出Toast。

另外:onPreferenceTreeClick()這個方法感覺和OnPreferenceClickListener的回調方法onPreferenceClick()的作用差不多,一樣是響應點擊的事件。

回頭再看OnPreferenceChangeListener的文檔:

Interface definition for a callback to be invoked when the value of this Preference has been changed by the user and is about to be set and/or persisted. This gives the client a chance to prevent setting and/or persisting the value.

就非常明白了~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章