自从写了上篇博客之后,总觉的太烦琐,太麻烦,而且容易报错和不容易维护,而且是从外部的角度来考虑,不是通过组件本身的角度,总之经过再三的考虑之后,还是决定改一下,精简和优化一下。
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; } @Override public 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())); //更新picker super.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; } @Override public 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); //备注1 super.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() { @Override public void onClick(View v) { // TODO Auto-generated method stub DatePickerDialog.OnDateSetListener listener = new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { // TODO Auto-generated method stub year1 = 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() { @Override public void onClick(View v) { OnTimeSetListener listener = new OnTimeSetListener() { @Override public void onTimeSet(TimePicker view, int hourOfDay, int minute) { boolean isSetTime = isNowTime(flag, hourOfDay, minute); //备注3 if(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