Android中同时选择日期和时间

最近在做一个项目,要求选择时间的控件是同时选择日期和小时和分钟,但是android中系统只有单独的日期DatePicker和TimePicker,所以就要自己写来组合一下。

首先是布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <DatePicker
            android:id="@+id/DatePicker"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />

        <TimePicker
            android:id="@+id/TimePicker"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

</LinearLayout>

 布局文件很简单,把焦点设给父亲布局是为了不要一点开这个控件就弹出键盘。

代码如下:

package cn.com.egova.mobileinspector.community.view;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;

import cn.com.egova.mobileinspector.R;
import cn.com.egova.mobileinspector.constance.Format;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.DatePickerDialog.OnDateSetListener;
import android.app.TimePickerDialog;
import android.app.TimePickerDialog.OnTimeSetListener;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.DatePicker.OnDateChangedListener;
import android.widget.LinearLayout;
import android.widget.TimePicker;
import android.widget.TimePicker.OnTimeChangedListener;
import android.widget.Toast;

public class DateTimeButton extends Button {
	public Calendar time = Calendar.getInstance(Locale.CHINA);
	public static final SimpleDateFormat format = new SimpleDateFormat(Format.DATA_FORMAT_YMDHMS_EN.toString());
	private DatePicker datePicker;
	private TimePicker timePicker;

	private Button dataView;
	private AlertDialog dialog;
//	private Activity activity;
	public DateTimeButton(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public DateTimeButton(Context context) {
		super(context);
		init();
	}
	
	//增加构造器
	public DateTimeButton(Context context,Button dataView){
		super(context);
		this.dataView = dataView;
	}
	
	public AlertDialog dateTimePickerDialog(){
		LinearLayout dateTimeLayout = (LinearLayout)LayoutInflater.from(getContext()).inflate(R.layout.date_time_picker, null);
		datePicker = (DatePicker) dateTimeLayout.findViewById(R.id.DatePicker);
		timePicker = (TimePicker) dateTimeLayout.findViewById(R.id.TimePicker);
		if(dataView == null)
			init();
		timePicker.setIs24HourView(true);
		
		
		OnTimeChangedListener timeListener= new OnTimeChangedListener() {
			
			@Override
			public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
				// TODO Auto-generated method stub
				time.set(Calendar.HOUR_OF_DAY, hourOfDay);
				time.set(Calendar.MINUTE, minute);
				
			}
		};

		timePicker.setOnTimeChangedListener(timeListener);
		
		OnDateChangedListener dateListener = new OnDateChangedListener() {
			
			@Override
			public void onDateChanged(DatePicker view, int year, int monthOfYear,
					int dayOfMonth) {
				// TODO Auto-generated method stub
				time.set(Calendar.YEAR, year);
				time.set(Calendar.MONTH, monthOfYear);
				time.set(Calendar.DAY_OF_MONTH, dayOfMonth);
				
			}
		};

		datePicker.init(time.get(Calendar.YEAR), time.get(Calendar.MONTH), time.get(Calendar.DAY_OF_MONTH), dateListener);
		timePicker.setCurrentHour(time.get(Calendar.HOUR_OF_DAY));
		timePicker.setCurrentMinute(time.get(Calendar.MINUTE));
		
		
		dialog = new AlertDialog.Builder(getContext()).setTitle("设置日期时间").setView(dateTimeLayout)
				.setPositiveButton("确定", new DialogInterface.OnClickListener() {
					
					@Override
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub
						
						time.set(Calendar.YEAR, datePicker.getYear());
						time.set(Calendar.MONTH, datePicker.getMonth());
						time.set(Calendar.DAY_OF_MONTH, datePicker.getDayOfMonth());
						time.set(Calendar.HOUR_OF_DAY, timePicker.getCurrentHour());
						time.set(Calendar.MINUTE, timePicker.getCurrentMinute());
						
						updateLabel();
					}
				}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
					
					@Override
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub
						
					}
				}).show();
		return dialog;
	}
	/**
	 * 
	 */
	private void init() {
		this.setBackgroundResource(R.drawable.datebutton_bg);
		this.setGravity(Gravity.LEFT);
		this.setTextColor(Color.BLACK);

		this.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// 生成一个DatePickerDialog对象,并显示。显示的DatePickerDialog控件可以选择年月日,并设置
				dateTimePickerDialog();
			}
		});
		
		updateLabel();
	}

	/**
	 * 更新标签
	 */
	public void updateLabel() {
		if(dataView != null){
			dataView.setText(format.format(time.getTime()));
		}
		this.setText(format.format(time.getTime()));
		
	}

	/**
	 * @return 获得时间字符串"yyyy-MM-dd HH:mm:ss"
	 */
	public String getDateString() {
		return format.format(time.getTime());
	}
	
	public void setDate(String datestr){
		try {
			time.setTime(format.parse(datestr));
			updateLabel();
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}

}

 按理说这样就行了,我之前以为也是这样,因为为测试了,是OK的,但是只要你点击控件上的加减来修改日期或者时间,点击确定那么是可以修改和保存成功的,可是大家都知道,日期控件和时间控件里面的输入框是可以手动输入的,这样我才发现如果我手输,点击确定,时间没有进行修改,这可难住我了。

还好,我经过点击发现,在一个输入框中修改了数字之后直接点击确定,那么是没有响应timechangelisterner的或者datechangelisterner,都没有响应,但是输入之后,移到另外一个输入框,这个时候就响应了,同时时间也被修改了,所以我想到了,在输入完成后,点击确定的时候,将DatePicker和TimePicker的焦点清除不就行了。于是,请在代码的103行加入这两句:

datePicker.clearFocus();
						timePicker.clearFocus();

 这样就搞定了,经过测试,没问题。

相关推荐