DatePickerDialog初次使用,所遇到的一些坑

原创 2016年08月29日 20:20:06

一、类结构

不管怎样,先把类的继承关系搞清楚。可以上去下边的网址上查看。

http://www.android-doc.com/reference/packages.html

DatePickerDialog 类结构:

public class
DatePickerDialog
extends AlertDialog
implements DialogInterface.OnClickListener DatePicker.OnDateChangedListener
java.lang.Objectandroid.app.Dialogandroid.app.AlertDialogandroid.app.DatePickerDialog

通过以上,我们可以发现,DatePickerDialog实现了OnClickListenerOnDateChangedListener这两个接口。不难猜测,我们在该控件上的一些操作,可以被这两个接口监听到,并完成一些诸如日期读取的动作。

二、简单使用

DatePickerDialog的简单使用,代码如下:
DatePickerDialog picker = new DatePickerDialog(this, new OnDateSetListener() {
    @Override
    public void onDateSet(DatePicker view, int year,
            int monthOfYear, int dayOfMonth) {
            // TODO Auto-generated method stub
            //这里获取日期
        }
    }, 2016, 8, 24);
    picker.show();

当对话框显现出来,是这样的:中间可手动修改日期值,也可拖动以改变日期值。

这里写图片描述

我们发现,对话框中间显现的时间,是我们上边在构造函数中传入的三个参数,2016、8、24.既然值是手动设置的,那么我们可以将其设为当前日期,在参数位置依次传入

Calendar.getInstance().get(Calendar.YEAR), 
Calendar.getInstance().get(Calendar.MONTH), 
Calendar.getInstance().get(Calendar.DATE)

这样,对话框显示的,就是当前日期了。

三、使用时出现的问题

首先,要注意一点,在编程语言中,很多计数,都是从0开始的,Android也不例外。日期是比较特殊的,因为没有0月一说,又,计数是从0开始的,所以,代码中所能设置的有效月份,范围是从0-11,分别代表了1-12月份。

1. 点击dialog以外空白部分,dialog消失,onDateSet仍执行了?

有这样一个需求:点击按钮出现日期选择对话框,选择完成后,点击确定,将所选日期,显示在界面上。刚做的时候,写了类似上边的代码,具体如下:

DatePickerDialog picker = new DatePickerDialog(this,
        new OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker view, int year,
                    int monthOfYear, int dayOfMonth) {
                // TODO Auto-generated method stub
                monthOfYear += 1;
                date_tv.setText(year + "-" + monthOfYear + "-"
                                + dayOfMonth);
            }
        }, Calendar.getInstance().get(Calendar.YEAR), Calendar
                .getInstance().get(Calendar.MONTH), Calendar
                .getInstance().get(Calendar.DATE));
picker.show();

使用过程中,发现,当我点击dialog以外的地方,dialog消失,textview上却仍然显示了dialog中间的日期值。也就是说,虽然我没有点击完成按钮,onDateSet仍然执行了。

我们在所实现的onDateSet中,做一些输出,以确定onDateSet执行了。我们发现,虽然我们并没有点击“完成”按钮,但是,输出了,onDateSet确实执行了。

之前有一个习惯性思维,以为只要没有点击“完成”、“确定”等按钮,相应的事件是不能被触发的。

那么,在我没有点击“完成”的情况下,onDateSet为什么执行了呢?

2. 在dialog上添加了两个按钮ok、cancel,其OnclickListener与onDateSet执行的先后顺序?

有时候,要求在dialog上,有一个确定、一个取消俩按钮。那么,我们可以这样做:

picker.setButton(DialogInterface.BUTTON_POSITIVE, "OK",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                });

        picker.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                });

出来的样式,是这样的:

然后,我习惯性地认为,onClick后于onDateSet执行。以为,在控件上选择好了日期后,点击ok按钮,我在onDateSet中得到的值,在onClick中可以直接使用了。代码如下;

private String date;

@Override
    public void onDateSet(DatePicker view, int year,
        int monthOfYear, int dayOfMonth) {
        // TODO Auto-generated method stub
        monthOfYear += 1;
        date = year + "-" + monthOfYear + "-"+ dayOfMonth;
    }

    picker.setButton(DialogInterface.BUTTON_POSITIVE, "OK",
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    System.out.println(date);
                }
            });

这样点击ok之后,我们可以发现,其实date中是没有值的。

那么,setButton后,其onClick与onDateSet的执行的先后顺序,是怎样的呢?

四、源码探究

通过查阅源码,可以发现,

private final OnDateSetListener mCallBack;
   /**
     * The callback used to indicate the user is done filling in the date.
     */
    public interface OnDateSetListener {

        /**
         * @param view The view associated with this listener.
         * @param year The year that was set.
         * @param monthOfYear The month that was set (0-11) for compatibility
         *  with {@link java.util.Calendar}.
         * @param dayOfMonth The day of the month that was set.
         */
        void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth);
}
mCallBack只在这个函数中调用,
    private void tryNotifyDateSet() {
        if (mCallBack != null) {
            mDatePicker.clearFocus();
            mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(),
                    mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
        }
}
而tryNotifyDateSet()只在两个地方调用,
    @Override
    protected void onStop() {
        tryNotifyDateSet();
        super.onStop();
    }
public void onClick(DialogInterface dialog, int which) {
        tryNotifyDateSet();
    }

这样,不难看出,onDateSet()在dialog消失时,调用了一次,在onClick中,也调用了一次。

五、解决问题

这样,上面出现的两个问题,就很好解决了。

问题1:在我没有点击“完成”的情况下,onDateSet为什么执行了呢?

解决:原因是,DatePickerDialog消失后,会调用onStop(),而在onStop()中,执行了tryNotifyDateSet(),在tryNotifyDateSet()中,又调用了onDateSet。所以,无论我们如何操作,最终,都会调用onDateSet。

问题2:setButton后,onClick与onDateSet的执行的先后顺序,是怎样的呢?

解决:点击Button后,首先调用的是我们实现的onClick(),其次,在dialog消失后,调用onDateSet()。

实验

其实还有一个简单粗暴有效的实验方法,来佐证。我们可以自定义一个IDatePickerDialog,代码照搬DatePickerDialog源码,将其中一些小错误修正后,就可以随便折腾啦~

版权声明:本文为博主原创文章,未经博主允许不得转载。

DatePickerDialog的使用

  • 2015年06月19日 18:43
  • 2KB
  • 下载

android—DatePicker 和TimePicker显示日期以及使用TimePickerDialog,DatePickerDialog来专门实现时间选择对话框

datePicker 和timePicker 显示日期和时间的控件 1.二个控件初始化 2.int定义 年 月 日 时 分 3.Calendar  类时间操作 创建Calendar对象 要 Ca...

DatePickerDialog日期的使用

  • 2015年09月13日 21:54
  • 5.29MB
  • 下载

Android DatePickerDialog的使用

  • 2013年07月01日 15:38
  • 4KB
  • 下载

DatePickerDialog.日期控件的简单使用

总结对日期控件的使用: xml version="1.0" encoding="utf-8"?>      LinearLayout xmlns:android="http://schem...

安卓原生自带的日期选择器DatePickerDialog、时间选择器TimePickerDialog使用方法

安卓原生自带的日期选择器DatePickerDialog、时间选择器TimePickerDialog使用方法 XML布局如下图: 代码实现如下: public...

android学习--DatePickerDialog和TimePickerDialog的使用

yi
  • dslinmy
  • dslinmy
  • 2014年08月09日 21:53
  • 898

Android中DatePickerDialog对话框和TimePickerDialog对话框的使用

DatePickerDialog对话框和TimePickerDialog对话框比单独的DatePicker组件和TimePicker组件更好用,用法也比较简单,下面通过一个简单实例来演示它们的使用: ...

Android开发小知识-TimePickerDialog和DatePickerDialog的使用

须知compileSdkVersion 23 buildToolsVersion 23.0.2 minSdkVersion 15 targetSdkVersion 23本例使用DialogFra...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:DatePickerDialog初次使用,所遇到的一些坑
举报原因:
原因补充:

(最多只允许输入30个字)