屋顶小黑猫 2013-03-07
最近在做一个项目,要求选择时间的控件是同时选择日期和小时和分钟,但是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();
这样就搞定了,经过测试,没问题。