版權(quán)聲明:本文為博主原創(chuàng)文章谆奥,轉(zhuǎn)載請注明出處http://www.reibang.com/p/4693b86c4da9
AndroidX中自定義DialogPreference和android framework以及support庫的不太一樣囤采,翻了官網(wǎng)文檔發(fā)現(xiàn)也沒有介紹灾炭,網(wǎng)上幾乎也搜索不到相關(guān)資料,于是只能翻了sdk源代碼來尋找方法佣蓉,特此記錄腊尚,給有需要的同學英遭。
案例
做一個設置界面,其中有一個設置項是用來選擇時間是己,因為界面選擇了PreferenceFragmentCompat
,所以最佳的做法就是自定義一個Preference任柜,使得點擊之后彈出一個TimePicker
用來選擇時間卒废。于是定下目標,自定義類TimePickerPreference
宙地,實現(xiàn)點擊彈出時間選擇界面并自動保存值的效果摔认。
實踐
要完成任務,我們需要實現(xiàn)三個類宅粥,才能達到效果参袱。
TimePickerPreference
在AndroidX中,官方把Preference的UI和數(shù)據(jù)部分分離了開來秽梅,而TimePickerPreference就是用來處理數(shù)據(jù)存儲讀取的抹蚀。TimePickerPreference繼承自androidx.preference.DialogPreference
。
public void setTime(int time) {
final boolean wasBlocking = shouldDisableDependents();
timeInMinute = time;
persistInt(time);
final boolean isBlocking = shouldDisableDependents();
if (isBlocking != wasBlocking) {
notifyDependencyChange(isBlocking);
}
showSummary();
notifyChanged();
}
public int getTime() {
return timeInMinute;
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getInt(index, 0);
}
@Override
protected void onSetInitialValue(Object defaultValue) {
if (defaultValue == null)
defaultValue = 0;
setTime(getPersistedInt((Integer) defaultValue));
}
注意上面代碼中的兩個Override方法企垦,這就是必須要實現(xiàn)的兩個方法环壤,當然,還有其它方法钞诡,比如onSaveInstanceState
之類的方法郑现,文章最后會給出完整的源代碼湃崩。
TimePickerDialogFragmentCompat
TimePickerDialogFragmentCompat負責UI層的構(gòu)建,繼承自androidx.preference.PreferenceDialogFragmentCompat
懂酱。
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
picker = view.findViewById(R.id.time_picker);
picker.setIs24HourView(true);
picker.setCurrentHour(timeInMinute / 60);
picker.setCurrentMinute(timeInMinute % 60);
}
private TimePickerPreference getTimePickerPreference() {
return (TimePickerPreference) getPreference();
}
@Override
public void onDialogClosed(boolean positiveResult) {
if (positiveResult) {
final TimePickerPreference preference = getTimePickerPreference();
timeInMinute = calCurrentTime();
if (preference.callChangeListener(timeInMinute)) {
preference.setTime(timeInMinute);
}
}
}
同樣注意上面代碼中的兩個Override方法竹习,這就是必須要實現(xiàn)的兩個方法,當然列牺,也有其它方法整陌,比如同樣的onSaveInstanceState
之類的方法。注意瞎领,由于是負責構(gòu)建UI的部分泌辫,其實它就是一個fragment,所以同樣的九默,最好寫一個newInstance方法用來構(gòu)造對象震放,這樣系統(tǒng)恢復此實例時會自動恢復其中的argument。文章的最后會給出完整的源代碼驼修。
MainFragment
最后就是我們用來展示自定義preference的界面了殿遂,假設叫MainFragment
,繼承自androidx.preference.PreferenceFragmentCompat
乙各,只要復寫其中的一個方法就可以了墨礁。
@Override
public void onDisplayPreferenceDialog(Preference preference) {
if (preference instanceof TimePickerPreference) {
TimePickerDialogFragmentCompat f = TimePickerDialogFragmentCompat.newInstance(preference.getKey());
f.setTargetFragment(this, 0);
f.show(getFragmentManager(), TimePickerDialogFragmentCompat.FRAGMENT_TAG);
return;
}
super.onDisplayPreferenceDialog(preference);
}
大功告成
完整源碼: