自從寫了上篇部落格之後,總覺的太煩瑣,太麻煩,而且容易報錯和不容易維護,而且是從外部的角度來考慮,不是通過組件本身的角度,總之經過再三的考慮之後,還是決定改一下,精簡和最佳化一下。
1,首先一進來,便是兩個簡單的TextView,然後日期和時間,時間是我亂寫的,日期是今天的。
2,當我點擊日期的TextView的時候會彈出一個對話方塊,DatePickerDialog,因為今天是8月14,當我點擊“-”號的時候,“-”號和中間顯示數位組件都被置成了不可按的狀態,強迫使用者不去選以前的日子,只能選擇以後的日子。
3,當日期選擇之後,點擊時間的TextView,然後會彈出一個時間的對話方塊,TimePickerDialog,當我選擇以前的時間,顯示和TimePicker都會被初始化為目前時間
4,可以看到3中選擇了15:02,因為時間到期,所以TextView和TimePicker都會被初始化為目前時間。
5,如果是不到期的時間,即將來的時間,則不會初始化。
6,如果日期是今天之後的日子,那麼時間不論怎麼設定都行。
在這裡重寫了DatePickerDialog:
/** * type為1的話則代表以後的日期是到期的,為2的話則代表以前的日期是到期的 * @author david * */public class MyDatePicker extends DatePickerDialog {private int type = -1;public MyDatePicker(Context context, OnDateSetListener callBack, int year,int monthOfYear, int dayOfMonth) {super(context, callBack, year, monthOfYear, dayOfMonth);}public MyDatePicker(Context context, OnDateSetListener callBack, int year,int monthOfYear, int dayOfMonth, int type) {super(context, callBack, year, monthOfYear, dayOfMonth);this.type = type;}@Overridepublic void onDateChanged(DatePicker view, int year, int month, int day) {Date time = new Date();//目前日期Date nextTime = new Date();//將要設定的日期,把值傳入其中nextTime.setYear(year - 1900);nextTime.setMonth(month);nextTime.setDate(day);if(view != null){if(type == 1){if ((nextTime.getTime() - time.getTime())>=0) { ((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(0)).getChildAt(0).setEnabled(false); ((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(1)).getChildAt(0).setEnabled(false); ((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(2)).getChildAt(0).setEnabled(false); ((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(0)).getChildAt(1).setEnabled(false); ((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(1)).getChildAt(1).setEnabled(false); ((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(2)).getChildAt(1).setEnabled(false); super.updateDate(time.getYear()+1900, time.getMonth(), (time.getDate()));}else{ ((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(0)).getChildAt(0).setEnabled(true); ((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(1)).getChildAt(0).setEnabled(true); ((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(2)).getChildAt(0).setEnabled(true); ((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(0)).getChildAt(1).setEnabled(true); ((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(1)).getChildAt(1).setEnabled(true); ((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(2)).getChildAt(1).setEnabled(true); super.onDateChanged(view, year, month, day);}}else if(type == 2){if ((nextTime.getTime() - time.getTime()) <= 0) {((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(0)).getChildAt(2).setEnabled(false);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(1)).getChildAt(2).setEnabled(false);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(2)).getChildAt(2).setEnabled(false);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(0)).getChildAt(1).setEnabled(false);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(1)).getChildAt(1).setEnabled(false);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(2)).getChildAt(1).setEnabled(false);super.updateDate(time.getYear() + 1900, time.getMonth(),(time.getDate()));//更新pickersuper.onDateChanged(view, year, month, day);} else {((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(0)).getChildAt(2).setEnabled(true);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(1)).getChildAt(2).setEnabled(true);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(2)).getChildAt(2).setEnabled(true);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(0)).getChildAt(1).setEnabled(true);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(1)).getChildAt(1).setEnabled(true);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(2)).getChildAt(1).setEnabled(true);super.updateDate(year, month, day);super.onDateChanged(view, year, month, day);//更新標題}}}}}
當然如果只是日期,不考慮時間的話,以上就可以了。現在要考慮時間的話,我本來打算跟重寫日期對話方塊一樣,重寫時間對話方塊,採用一樣的重寫方法,可是發現,在重寫裡面的TimePicker重新賦值總是會報棧溢出錯誤,TimePicker放在外面來賦值卻又沒錯,詭異的很,具體代碼:
public class MyTimePicker extends TimePickerDialog{private boolean isSet;private int hour,minute;public MyTimePicker(Context context, OnTimeSetListener callBack,int hourOfDay, int minute, boolean is24HourView,boolean isSet) {super(context, callBack, hourOfDay, minute, is24HourView);this.isSet = isSet;this.hour = hourOfDay;this.minute = minute;}@Overridepublic void onTimeChanged(TimePicker view, int hourOfDay, int minute) {Date time = new Date();//目前日期Date nextTime = new Date();//將要設定的日期,把值傳入其中nextTime.setHours(hourOfDay);nextTime.setMinutes(minute);if(view != null){if(!isSet){Log.i("test","日期等於今天,時間有限制");if(nextTime.getTime() - time.getTime() <= 0){Log.i("test","hour1:"+hourOfDay+",minut:"+minute);Log.i("test","日期等於今天,時間小於等於現在,不能按 - 號按鈕");((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(0)).getChildAt(2).setEnabled(false);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(1)).getChildAt(2).setEnabled(false);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(0)).getChildAt(1).setEnabled(false);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(1)).getChildAt(1).setEnabled(false);updateTime(hour, minute);//備忘1super.onTimeChanged(view, hourOfDay, minute);}else{Log.i("test","日期等於今天,時間大於現在,可以按 - 號按鈕");Log.i("test","hour2:"+time.getHours()+",minut:"+time.getMinutes());((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(0)).getChildAt(2).setEnabled(true);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(1)).getChildAt(2).setEnabled(true);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(0)).getChildAt(1).setEnabled(true);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(1)).getChildAt(1).setEnabled(true);this.hour = hourOfDay;this.minute = minute;super.onTimeChanged(view, hourOfDay, minute);}}else{Log.i("test","日期大於今天,時間隨便選");((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(0)).getChildAt(2).setEnabled(true);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(1)).getChildAt(2).setEnabled(true);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(0)).getChildAt(1).setEnabled(true);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(1)).getChildAt(1).setEnabled(true);this.hour = hourOfDay;this.minute = minute;super.onTimeChanged(view, hourOfDay, minute);}}}public void setIsSet(boolean isSet){this.isSet = isSet;}public void setHour(int hour) {this.hour = hour;}public void setMinute(int minute) {this.minute = minute;}public int getHour(){return hour;}public int getMinute(){return minute;}}
備忘1:這裡的邏輯是這樣的:當我選擇的時間小於目前時間的話,那麼把TimePickerDialog下面的“-”和中間的組件都設定成灰色不可按的,同時備忘1出代碼的作用就是把TimePicker的值初始話為當前的時間,updateTIme方法在父類中的源碼如下:
public void updateTime(int hourOfDay, int minutOfHour) { mTimePicker.setCurrentHour(hourOfDay); mTimePicker.setCurrentMinute(minutOfHour); }
可以看到只是給TimePicker初始化的錯做,可是在這裡初始化這個組件的時候會報錯:
想了很久,也不知道原因,於是就打算不重寫TimePickerDialog,效果看起來雖然沒有日期的效果那麼來的直觀,但是比前面的已經要好多了。
下面看看主類的調用:
hello.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubDatePickerDialog.OnDateSetListener listener = new DatePickerDialog.OnDateSetListener() {@Overridepublic void onDateSet(DatePicker view, int year, int monthOfYear,int dayOfMonth) {// TODO Auto-generated method stubyear1 = year;month1 = monthOfYear;day1 = dayOfMonth;updateDisplay1();flag = isNowDate(year1,month1,day1); //備忘2}};new MyDatePicker(MainActivity.this, listener, year1, month1, day1, 2).show();}});world.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {OnTimeSetListener listener = new OnTimeSetListener() {@Overridepublic void onTimeSet(TimePicker view, int hourOfDay, int minute) {boolean isSetTime = isNowTime(flag, hourOfDay, minute); //備忘3if(view != null){if(!isSetTime){((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(0)).getChildAt(2).setEnabled(false);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(1)).getChildAt(2).setEnabled(false);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(0)).getChildAt(1).setEnabled(false);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(1)).getChildAt(1).setEnabled(false);initTimePicker(view, new Date().getHours(), new Date().getMinutes());//time1.onTimeChanged(view, hourOfDay, minute);updateDisplay2(new Date().getHours(), new Date().getMinutes());}else{((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(0)).getChildAt(2).setEnabled(true);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(1)).getChildAt(2).setEnabled(true);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(0)).getChildAt(1).setEnabled(true);((ViewGroup) ((ViewGroup) view.getChildAt(0)).getChildAt(1)).getChildAt(1).setEnabled(true);updateDisplay2(hourOfDay,minute);}}}};time1 = new TimePickerDialog(MainActivity.this,listener , Integer.parseInt(world.getText().toString().split(":")[0].trim()), Integer.parseInt(world.getText().toString().split(":")[1].trim()), true);time1.show();}});}
備忘2:這裡是根據設定的日期和當前的日期進行比較得到一個boolean值,來決定對時間要不要進行限制
備忘3:這裡是根據設定時間和目前時間進行比較得到一個boolean值,來決定如何初始化時間組件
Demo下載:http://download.csdn.net/detail/duancanmeng/4499365