时间选择器中onDateSet/onTimeSet执行两次
来源:互联网 发布:js是什么文件 编辑:程序博客网 时间:2024/06/11 13:26
一 编写目的
虽然目前有很多的时间选择控件可以给开发者使用,但有的时候由于使用行业,手机页面布局,手机屏幕等因素,我们还是需要使用android自带的时间选择控件。我最近使用系统时间选择控件的时候,发现了一个问题,就是高版本的系统中onDateSet方法会调用两次,这就意味着低版本中在onDateSet中实现的逻辑在高版本中会执行两次,这样就会给我们软件的兼容问题带来一些麻烦,因此这个地方把解决方法记录下,方便大家学习。
二 问题原因
我手中有几台不同系统版本的手机,发现在4.3系统后的(下面就是4.1版本,4.2没测试过)版本中运行测试代码的时候,onDateSet中打印日志执行两次,而低版本的只执行了一次,这就说明很有可能是高版本系统在这个地方做了修改,因此我去查阅了下系统源码,对比一下,发现了其中问题。
低版本的源码:
public void onClick(DialogInterface dialog, int which) { if (mCallBack != null) { mDatePicker.clearFocus(); mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(), mDatePicker.getMonth(), mDatePicker.getDayOfMonth()); } }
就是说点击确定或取消按钮的时候会执行onDateSet方法。
高版本的源码:
public void onClick(DialogInterface dialog, int which) { tryNotifyDateSet(); } private void tryNotifyDateSet() { if (mCallBack != null) { mDatePicker.clearFocus(); mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(), mDatePicker.getMonth(), mDatePicker.getDayOfMonth()); } } @Override protected void onStop() { tryNotifyDateSet(); super.onStop(); }
从此源码中可以看出,相较于低版本的源码,高版本的源码中对应对话框的停止(onStop)也做了调用onDateSet方法,从而使点击确定或取消按钮时,该方法被执行了两次。
三 解决
比较两份源码,我们很容易得出一个解决方法,就是把高版本的onStop干掉。对头,我就是这么处理的,重载onStop方法,将里面的super.onStop()去掉。对于无其他特殊要求的情况下,这种貌似是没有副作用的,而且,我这样用后到目前为止也没有副作用体现出来。以下是重载方法:
public static class MyDatePickDialog extends DatePickerDialog {public MyDatePickDialog(Context context, OnDateSetListener callBack,int year, int monthOfYear, int dayOfMonth) {super(context, callBack, year, monthOfYear, dayOfMonth);// TODO Auto-generated constructor stub}public MyDatePickDialog(Context context, int theme,OnDateSetListener callBack, int year, int monthOfYear,int dayOfMonth) {super(context, theme, callBack, year, monthOfYear, dayOfMonth);// TODO Auto-generated constructor stub}@Overrideprotected void onStop() {// TODO Auto-generated method stub}}
同理,TimePickerDialog的解决方式和这个一样,就不累述了。
四 一个自定义的时间选择示例
功能:通过继承EditText,达到点击输入框(或者调用里面的触发时间),然后弹出日期供选择,选完日期后,接着弹出时间来供选择,最后将选择的时间日期填写到输入框中。以下是代码:
package com.urovo.stocity.view.custom;import java.util.Calendar;import java.util.Date;import utils.DateUtil;import android.app.DatePickerDialog;import android.app.DatePickerDialog.OnDateSetListener;import android.app.Dialog;import android.app.TimePickerDialog;import android.app.TimePickerDialog.OnTimeSetListener;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.View;import android.widget.DatePicker;import android.widget.EditText;import android.widget.TimePicker;/** * input method will need to run in a limited "generate key events" mode. * * * @author admin * */public class DateTimeEditText extends EditText implements OnDateSetListener,OnTimeSetListener {public MyDatePickDialog Dlg;public Dialog timeDialog;private Context context;private String timeStr;public DateTimeEditText(Context context) {super(context);this.context = context;setListener();}public DateTimeEditText(Context context, AttributeSet attrs) {super(context, attrs);this.context = context;setListener();}private void setListener() {this.setFocusable(false);this.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubinitCalendar();Dlg.show();}});}public void dateSelect() {// 此方法为弹出时间选择对话框,可在外部调用initCalendar();Dlg.show();}private void initCalendar() {String dateStr = this.getText().toString().trim();Date date = DateUtil.parseCompleteDate(dateStr);if (date == null) {// 如果输入框内初始为空,则将当前时间初始为日期时间date = new Date();}Calendar d = Calendar.getInstance();d.setTimeInMillis(date.getTime());// 初始化时间选择器int year = d.get(Calendar.YEAR);int month = d.get(Calendar.MONTH);int day = d.get(Calendar.DAY_OF_MONTH);Dlg = new MyDatePickDialog(context, this, year, month, day);Dlg.setCanceledOnTouchOutside(false);timeDialog = new MyTimePickerDialog(context, this,d.get(Calendar.HOUR_OF_DAY), d.get(Calendar.MINUTE), true);timeDialog.setTitle("请选择时间");}@Overridepublic void onDateSet(DatePicker view, int year, int monthOfYear,int dayOfMonth) {// TODO Auto-generated method stubtimeStr = year + "-"+ (monthOfYear < 9 ? "0" + (monthOfYear + 1) : monthOfYear + 1)+ "-" + (dayOfMonth < 10 ? "0" + dayOfMonth : dayOfMonth) + " ";timeDialog.show();Log.e("aa", "onDateSet");}@Overridepublic void onTimeSet(TimePicker view, int hourOfDay, int minute) {// TODO Auto-generated method stubtimeStr += (hourOfDay < 10 ? "0" + hourOfDay : hourOfDay) + ":"+ (minute < 10 ? "0" + minute : minute) + ":00";DateTimeEditText.this.setText(timeStr);Log.e("aa", "onTimeSet");}// 重写DatePickerDialog以避免两次执行onDateSet方法public static class MyDatePickDialog extends DatePickerDialog {public MyDatePickDialog(Context context, OnDateSetListener callBack,int year, int monthOfYear, int dayOfMonth) {super(context, callBack, year, monthOfYear, dayOfMonth);// TODO Auto-generated constructor stub}public MyDatePickDialog(Context context, int theme,OnDateSetListener callBack, int year, int monthOfYear,int dayOfMonth) {super(context, theme, callBack, year, monthOfYear, dayOfMonth);// TODO Auto-generated constructor stub}@Overrideprotected void onStop() {// TODO Auto-generated method stub}}public static class MyTimePickerDialog extends TimePickerDialog {public MyTimePickerDialog(Context context, OnTimeSetListener callBack,int hourOfDay, int minute, boolean is24HourView) {super(context, callBack, hourOfDay, minute, is24HourView);// TODO Auto-generated constructor stub}public MyTimePickerDialog(Context context, int theme,OnTimeSetListener callBack, int hourOfDay, int minute,boolean is24HourView) {super(context, theme, callBack, hourOfDay, minute, is24HourView);// TODO Auto-generated constructor stub}@Overrideprotected void onStop() {// TODO Auto-generated method stub}}}
五 结束
一个小小的总结,希望能帮到大家。
- 时间选择器中onDateSet/onTimeSet执行两次
- 五种简单Dialog的使用,以及时间,日期Dialog中onDateSet,onTimeSet被执行两次的Bug
- 解决TimePickerDialog中onTimeSet和 DatePickerDialog中onDateSet执行两次的问题
- TimerPickerDialog 中 onTimeSet 执行两次的问题
- onTimeSet执行两次问题
- 解决TimePickerDialog中onTimeSet执行两次的问题
- 解决TimePickerDialog中onTimeSet执行两次的问题
- 解决TimePickerDialog中onTimeSet执行两次的问题
- Android TimePickerDialog两次执行onTimeSet问题
- Android TimePickerDialog两次执行onTimeSet问题
- Android DatePickerDialog存在执行两次onDateSet BUG
- 针对高版本timpicker/datepicker中ontimeset执行两次的解决办法
- android对TimePickerDialog进行监听 onTimeSet会执行两次!
- DatePickerDialog onDateSet 调用两次解决方案
- 关于使用DatePickerDialog日期选择中onDateSet调用两次的问题
- Android TimePickerDialog 多次执行onTimeSet
- android 两次调用DatePickerDialog.onDateSet()
- struts2中action执行两次
- cocos2d-x中的精灵细说
- Java Http协议服务器demo
- Android 解决屏幕上自适应问题
- cocos2d-x中的动作细说
- 外键及其约束理解
- 时间选择器中onDateSet/onTimeSet执行两次
- Serial Programming Guide for POSIX Operating Systems
- ssl 密钥用法 增强密钥用法 证书类型
- iOS 面试(比较详细的知识点)
- 决定开始走的路
- ios 开发中继承
- 实际用户ID,有效用户ID和设置用户ID
- 【Code Forces】221D - Little Elephant and Array(线段树,思维做法)
- .net 导出excel 数字文本