Android学习笔记:设置日期和时间不能选择当前时刻以前的日期时间的解决方法升级版

Android学习笔记:设置日期和时间不能选择当前时刻以前的日期时间的解决办法升级版

自从写了上篇博客之后,总觉的太烦琐,太麻烦,而且容易报错和不容易维护,而且是从外部的角度来考虑,不是通过组件本身的角度,总之经过再三的考虑之后,还是决定改一下,精简和优化一下。

1,首先一进来,便是两个简单的TextView,然后日期和时间,时间是我乱写的,日期是今天的。

Android学习笔记:设置日期和时间不能选择当前时刻以前的日期时间的解决方法升级版

2,当我点击日期的TextView的时候会弹出一个对话框,DatePickerDialog,因为今天是8月14,当我点击“-”号的时候,“-”号和中间显示数字的组件都被置成了不可按的状态,强迫用户不去选以前的日子,只能选择以后的日子。

Android学习笔记:设置日期和时间不能选择当前时刻以前的日期时间的解决方法升级版

3,当日期选择之后,点击时间的TextView,然后会弹出一个时间的对话框,TimePickerDialog,当我选择以前的时间,显示和TimePicker都会被初始化为当前时间

Android学习笔记:设置日期和时间不能选择当前时刻以前的日期时间的解决方法升级版

4,可以看到3中选择了15:02,因为时间过期,所以TextView和TimePicker都会被初始化为当前时间。

Android学习笔记:设置日期和时间不能选择当前时刻以前的日期时间的解决方法升级版

5,如果是不过期的时间,即将来的时间,则不会初始化。

Android学习笔记:设置日期和时间不能选择当前时刻以前的日期时间的解决方法升级版

6,如果日期是今天之后的日子,那么时间不论怎么设置都行。

Android学习笔记:设置日期和时间不能选择当前时刻以前的日期时间的解决方法升级版


在这里重写了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初始化的错做,可是在这里初始化这个组件的时候会报错:

Android学习笔记:设置日期和时间不能选择当前时刻以前的日期时间的解决方法升级版

想了很久,也不知道原因,于是就打算不重写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