19

我的应用程序在我的 Android 2.2 模拟器上运行良好。然后我决定在 Android 4.1 模拟器上进行测试。DatePickerDialog看起来有点不同,由于某种原因,当我按下“完成”时,侦听onDateSet()器被调用两次并导致我的应用程序出现问题。

我知道这一点,因为每当我点击“完成”时,代码中显示的日志就会打印两次

mDateSetListener = new DatePickerDialog.OnDateSetListener() {
    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
            Log.v("onDateSet", "ENTERED");
            //rest of code...
    }};

Android 2.2 日期选择器

工作Android 2.2 DatePicker

安卓 4.1 日期选择器

不工作的 Android 4.1 日期选择器

4

4 回答 4

25

尝试设置一个布尔值以检查同一对话框中的双重触发。类似于:

Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_YEAR, 1);
final DatePickerDialog dateDialog = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() {
    boolean fired = false;
    public void onDateSet(final DatePicker view, final int year, final int monthOfYear, final int dayOfMonth) {
        Log.i("PEW PEW", "Double fire check");
        if (fired) {
            Log.i("PEW PEW", "Double fire occured. Silently-ish returning");
            return;
        } else {
            //first time fired
            fired = true;
        }
        //Normal date picking logic goes here
    }
}, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH));
dateDialog.show();

TimePickerDialog 的 onTimeSet 也会发生这种双重触发问题,并且此检查也适用于这些问题。

于 2012-07-31T20:12:13.603 回答
1

根据 Ankur Chaudhary对类似问题的精彩回答TimePickerDialog,如果我们检查内部onDateSet是否给定视图isShown(),它将以最小的努力解决整个问题,无需扩展选择器或检查代码周围的一些可怕标志甚至检查操作系统版本,只需执行以下操作:

public void onDateSet(DatePicker view, int year, int month, int day) {
    if (view.isShown()) {
        // read the date here :)
    }
}

onTimeSet当然,根据 Ankur 的回答也可以这样做

于 2015-03-16T17:35:02.897 回答
0

我认为这是相关的,我今天开始在 4.1 上进行测试,发现一些 javascript 事件似乎触发了两次。目前主要是点击。奇怪的是,如果我添加警报,它“有时”会触发一次。这种行为奇怪地不一致。

javascript 事件仅在 android 4.1 上以这种方式响应。iPhone 似乎和我迄今为止尝试过的所有以前版本的 android 一样(包括 4.0.x)。

对我来说,这似乎是浏览器的错误或其处理 javascript 的方式,但这只是一个猜测。

于 2012-07-13T11:43:47.267 回答
0

重申:这是 Android 中已确认的错误。已经提出了两种解决方法,将状态保存在(实例)变量中或询问 Dialog if it isShown()。但isShown()似乎不可靠(例如根据这个答案的评论),如果你想重新显示对话框,保存状态会变得混乱。
更好的解决方案是将状态保存在 Dialog 本身内:

public void onDateSet(DatePicker picker, int year, int monthOfYear, int dayOfMonth) {
    if (picker.getTag() == null) {
        picker.setTag("TAGGED");
        // Only gets called once per Dialog
    }
}

它干净有效。

于 2015-04-29T13:29:00.163 回答