Android:Android 4.1 模拟器从 DatePicker 对话框调用 onDateSet 两次
Posted
技术标签:
【中文标题】Android:Android 4.1 模拟器从 DatePicker 对话框调用 onDateSet 两次【英文标题】:Android: Android 4.1 Emulator Invoking onDateSet Twice from DatePicker Dialog 【发布时间】:2012-07-08 04:12:07 【问题描述】:我的应用程序在我的 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 4.1 日期选择器
【问题讨论】:
2012 年 8 月 30 日模拟器上的相同问题 android 4.1,在这里投票code.google.com/p/android/issues/detail?id=34860 Jelly Bean DatePickerDialog --- is there a way to cancel?的可能重复 【参考方案1】:尝试设置一个布尔值以检查同一对话框中的双重触发。类似于:
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 也会发生这种双重触发问题,并且此检查也适用于这些问题。
【讨论】:
将fired
变量切换回 false
以便 DatePicker 之后继续工作。顺便说一句,问题也出现在 TimePicker 对话框中。
这个变通方法也适用于 TimePicker 对话框,方法是在创建时使用类似的“触发”检查。
OMG - 我一直在疯狂地试图弄清楚为什么日期选择器中的 onDateSet 中的代码不能正常工作,并且在一些 toastMEssages 意识到它被触发了两次之后。非常感谢 - 尝试调试 11 个小时,这就是那个该死的问题。谢谢!!!!
很乐意尽我所能提供帮助。
这是一个不完整的解决方案。 The bug 在按下“完成”按钮和关闭对话框时都在调用 onDateSet()
。后者也有问题,因为日期将在用户取消时设置(即按回或在对话框外点击)。此处发布的解决方案无法解决此问题。【参考方案2】:
根据 Ankur Chaudhary 在类似的TimePickerDialog
问题上的精彩answer,如果我们在onDateSet
内部检查给定视图isShown()
与否,它将以最小的努力解决整个问题,无需要扩展选择器或检查代码周围的一些可怕标志,甚至检查操作系统版本,只需执行以下操作:
public void onDateSet(DatePicker view, int year, int month, int day)
if (view.isShown())
// read the date here :)
当然,根据 Ankur 的回答,onTimeSet
也可以这样做
【讨论】:
【参考方案3】:我认为这是相关的,我今天开始在 4.1 上进行测试,发现一些 javascript 事件似乎触发了两次。目前主要是点击。 奇怪的是,如果我添加警报,它“有时”会触发一次。 这种行为奇怪地不一致。
javascript 事件仅在 android 4.1 上以这种方式响应。 iPhone 和我迄今为止尝试过的所有以前版本的 android 一样(包括 4.0.x)似乎都很好。
对我来说,这似乎是浏览器或其处理 javascript 的方式出错,但这只是猜测。
【讨论】:
对于如何解决这个错误有什么建议吗?有什么解决方法吗?:) 到目前为止我什么都没找到。除了上述之外,它似乎只发生在点击或触摸事件上。不是所有的事件。 (当我有时间时)我将在 android 错误列表上创建一个错误报告。【参考方案4】:重申:这是 Android 中已确认的错误。已经提出了两种解决方法,将状态保存在(实例)变量中或询问对话框是否为isShown()
。但是isShown()
似乎不可靠(例如,根据this answer's comments),如果您想重新显示对话框,保存状态会变得混乱。
更好的解决方案是将状态保存在 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
干净有效。
【讨论】:
以上是关于Android:Android 4.1 模拟器从 DatePicker 对话框调用 onDateSet 两次的主要内容,如果未能解决你的问题,请参考以下文章
在Android Studio中将Gradle从3.3升级到4.1后出错
Android studio 4.1 Emulator 扩展控件
pulltorefresh android 4.1及更高版本[重复]