在開發(fā)應(yīng)用程序的過程中我們有很大的機會需要用到參數(shù)設(shè)置功能,那么在Android應(yīng)用中,我們?nèi)绾螌崿F(xiàn)參數(shù)設(shè)置界面及參數(shù)存儲呢,下面我們來介紹一下Android中的一個特殊Activity–PreferencesActivity。PreferencesActivity是Android中專門用來實現(xiàn)程序設(shè)置界面及參數(shù)存儲的一個Activity,我們用一個實例來簡介如何使用PreferencesActivity。
下圖是一個參數(shù)設(shè)置界面:
設(shè)計自己的Android Preference
SeekBar Preference
Android提供了Preference供應(yīng)用可以進行功能設(shè)置以及屬性配置等操作,檢查android.preference可以看到Preference下有若干子類,例如常用的EditTextPreference、CheckBoxPreference、ListPreference等。但是僅僅有這些是不夠的。
在我現(xiàn)在的工作當(dāng)中,應(yīng)用里有這么一個場景,用戶手指在屏幕滑動,應(yīng)用繪制出移動的軌跡。
熟悉Android API Demo(可以在SDK/platforms/android-1.5/samples下找到)的人一定記得在graphics目錄下,有一個FingerPaint的類實現(xiàn)了類似上述功能。但是還遠遠實現(xiàn)不了我們的需要,–需求是要在Preference中實現(xiàn)挑選顏色和調(diào)整粗細。
當(dāng)然,他山之石可以攻玉,F(xiàn)ingerPaint還是提供了不錯的例子,尤其是FingPaint中選擇顏色所使用的另外一個類ColorPickerDialog基本上具備了我們想要的部分功能。
除了上面提到的FingerPaint之外,還可以從Android的源碼中找到可以參考的代碼。從framework/base/core/java中,找到android.preference包,可以看到有一個SeekBarPreference的類,–這是一個“爛尾”類,代碼未完成,因此被Google打上了@hide的標(biāo)簽。因此需要稍加完善,才能加以使用。
@Overrideprotected void onBindDialogView(View view) {super.onBindDialogView(view); bar = (SeekBar) view.findViewById(R.id.seekbar);bar.setOnSeekBarChangeListener(this);bar.setProgress(barValue);} public void setValue(int value) {barValue = value;} public int getValue() {return barValue;} @Overrideprotected void onDialogClosed(boolean positiveResult) {if (positiveResult) {this.getOnPreferenceChangeListener().onPreferenceChange(this, barValue);}}
Color Picker Preference
在這個類的改造過程中,override兩個父類方法是關(guān)鍵所在,一個是onBindDialogView,另一個是onDialogClosed。
通過第一個方法,我們可以“找到”被當(dāng)做content view的SeekBar的實例,進而可以獲得到其progress。
通過第二個方法,我們可以方便的通知到Listener,告訴它,SeekBar的值有變化。這里我們把SeekBar的值,即progress看做是SeekBarPreference的value。除了這兩個方法之外,就是要增加setValue和getValue兩個方法了。
如果不看代碼的話,就會有疑問:SeekBar是如何進入Diglog的呢?它正式通過DialogPreference的屬性android:dialogLayout得以注入:
<net.poemcode.android.config.SeekBarPreferenceandroid:key="@string/setting_handwrite_width_key"android:title="@string/setting_handwrite_width_title"android:dialogTitle="@string/setting_handwrite_width_title"android:dialogLayout="@layout/setting_widthseekbar"android:persistent="true"/>
依此原理,可以舉一反三,對于如何實現(xiàn)選擇顏色是不是有了思路?
首先實現(xiàn)一個視圖,負責(zé)展現(xiàn)不同顏色和接收用戶選中的顏色,其可以從SeekBarPreference中的內(nèi)部類ColorPickerView加以改造完成;然后新增一個布局文件,將剛才的視圖加入到布局當(dāng)中;接著繼承DialogPreference實現(xiàn)自己的Preference子類ColorPickerPreference;最后在XML文件里增加這個Preference并把剛才的布局文件通過dialogLayout屬性加入進去。從而實現(xiàn)了整個功能。
public class SeekBarPreference extends DialogPreference implements SeekBar.OnSeekBarChangeListener { private static final String TAG = "SeekBarPreference"; private SeekBar bar; private int barValue; public SeekBarPreference(Context context, AttributeSet attrs) {super(context, attrs);} @Overrideprotected void onBindDialogView(View view) {super.onBindDialogView(view); bar = (SeekBar) view.findViewById(R.id.seekbar);bar.setOnSeekBarChangeListener(this);bar.setProgress(barValue);} public void setValue(int value) {barValue = value;} public int getValue() {return barValue;} @Overrideprotected void onDialogClosed(boolean positiveResult) {if (positiveResult) {this.getOnPreferenceChangeListener().onPreferenceChange(this, barValue);}} public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {Log.d(TAG, "onProgressChanged, progress : " + progress + ", fromUser : " + fromUser);} public void onStartTrackingTouch(SeekBar seekBar) {Log.d(TAG, "onStartTrackingTouch");} public void onStopTrackingTouch(SeekBar seekBar) {barValue = seekBar.getProgress();}}