可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have this issue with my app when I call to show a dialog, it is being called twice somehow. This only happens with android 4.1 and above. Lower version works fine so I dont think it's any code issue.
Did you heard\encountered this issue before?
here the code:
Button edit = (Button) ad.findViewById(R.id.editBtn);
edit.setTypeface(roboto);
edit.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
setDate();
ad.dismiss();
}
});
ad.show();
ad.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
shiftsActivity.setPressed(true);
}
});
}
public void setDate() {
// Initialize and open the set date dialog
DatePickerDialog setDateDialog = new DatePickerDialog(Shifts.this,
datePickerListener, dateAndTime.get(Calendar.YEAR),
dateAndTime.get(Calendar.MONTH),
dateAndTime.get(Calendar.DAY_OF_MONTH));
setDateDialog.setTitle("Set Date");
setDateDialog.show();
}
public void setStartTime() {
TimePickerDialog setStartTimeDialog = new TimePickerDialog(Shifts.this,
startTimePicker, dateAndTime.get(Calendar.HOUR),
dateAndTime.get(Calendar.MINUTE), true);
setStartTimeDialog.setTitle("Started At:");
setStartTimeDialog.show();
}
public void setEndTime() {
TimePickerDialog setEndTimeDialog = new TimePickerDialog(Shifts.this,
setEndTime, dateAndTime.get(Calendar.HOUR),
dateAndTime.get(Calendar.MINUTE), true);
setEndTimeDialog.setTitle("Ended:");
setEndTimeDialog.show();
}
TimePickerDialog.OnTimeSetListener startTimePicker = new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
startIntHours = hourOfDay;
startIntMinutes = minute;
editStartTime = String.format("%02d", hourOfDay) + ":"
+ String.format("%02d", minute);
setEndTime();
}
};
TimePickerDialog.OnTimeSetListener setEndTime = new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
finishIntHours = hourOfDay;
finsihIntMinutes = minute;
if (finishIntHours < startIntHours) {
finishIntHours = finishIntHours + Utility.HOURS_TIME_UNIT;
}
if (finsihIntMinutes < startIntMinutes) {
finsihIntMinutes = finsihIntMinutes + Utility.MINUTES_TIME_UNIT;
}
totalHours = finishIntHours - startIntHours;
totalMinutes = finsihIntMinutes - startIntMinutes;
Log.i("TotalHours in time picker", "" + totalHours);
Log.i("Totalminute in time picker", "" + totalMinutes);
editEndTime = String.format("%02d", hourOfDay) + ":"
+ String.format("%02d", minute);
replace(Shifts.view, Shifts.position);
}
};
回答1:
According to your code, neither of those methods are ever called, because you never use the TimePickerDialogs
.
That being said, there is a known issue related to the behavior of DatePickerDialog
/TimePickerDialog
that may be relevant: http://code.google.com/p/android/issues/detail?id=34833
回答2:
Here is a basic solution, for someone who needs a TimeChooserDialog, that does not call the listener twice, with basic options
public static AlertDialog getTimePickerDialog(Context context, final OnTimeSetListener listener, int hour, int minute, boolean is24HFormat) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
final TimePicker timePicker = new TimePicker(context);
timePicker.setIs24HourView(is24HFormat);
timePicker.setCurrentHour(hour);
timePicker.setCurrentMinute(minute);
builder.setView(timePicker);
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
if(null != listener) {
listener.onTimeSet(timePicker, timePicker.getCurrentHour(), timePicker.getCurrentMinute());
}
}
});
builder.setNegativeButton(android.R.string.cancel, null);
return builder.create();
}
回答3:
If you look in the android source it appears that onTimeSet() gets called during onStop(). The dialog also calls onTimeSet() in it's onClick() method.
To get around this I had to override the dialogs dismiss and cancel functions to set a boolean which i checked if the onTimeSet was being called from the button click or dismiss/cancel
回答4:
The same issue is occurs with me for TimePicker. I solve that issue.
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int setHour, int setMinute) {
if (view.isShown()) {
// This method will return true only once
}
}
};
iShown() :
Returns the visibility of this view and all of its ancestors
Returns
True if this view and all of its ancestors are VISIBLE
回答5:
I try it and it is work good with me if you still have the problem try to use The classic singleton
Something like this :) read more about it.
public void setStartTime() {
TimePickerDialog setStartTimeDialog = NULL;
if(setStartTimeDialog == null) {
new TimePickerDialog(Shifts.this, startTimePicker, dateAndTime.get(Calendar.HOUR),dateAndTime.get(Calendar.MINUTE), true);
setStartTimeDialog.setTitle("Started At:");
}
setStartTimeDialog.show();
}
回答6:
Don't use the built-in TimePickerDialog or DatePickerDialog. Instead create a custom dialog like what is shown here. It's simple and easy to use and just works!
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
final TimePicker timePicker = new TimePicker(getActivity());
builder.setTitle("Set Time");
builder.setView(timePicker);
builder.setNegativeButton("Cancel", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.setPositiveButton("OK"), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
int minute = timePicker.getCurrentMinute();
int hourOfDay = timePicker.getCurrentHour();
}
});
builder.show();
回答7:
Rather than violate super.onClose() or making custom dialogs, I solve it with by wrapping real listener and extending TimePickerDialog that enabled and disables forwarding from wrapper to real listener. It's not a drop in replacement, but it's neat enough.
public class TimePickerDialogCustom extends TimePickerDialog
{
protected TimePickerDialogOnTimeSetListenerWrapper listenerWrapper;
public TimePickerDialogCustom(Context context,
TimePickerDialogOnTimeSetListenerWrapper listener,
int hourOfDay, int minute, boolean is24HourView)
{
super(context, listener, hourOfDay, minute, is24HourView);
listenerWrapper = listener;
}
@Override
protected void onStop()
{
if (listenerWrapper != null)
listenerWrapper.enabled = false;
super.onStop();
if (listenerWrapper != null)
listenerWrapper.enabled = true;
}
public static final class TimePickerDialogOnTimeSetListenerWrapper implements TimePickerDialog.OnTimeSetListener
{
private boolean enabled = true;
private final TimePickerDialog.OnTimeSetListener delegate;
public TimePickerDialogOnTimeSetListenerWrapper(TimePickerDialog.OnTimeSetListener delegate)
{
this.delegate = delegate;
}
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute)
{
if (enabled)
{
this.delegate.onTimeSet(view, hourOfDay, minute);
}
}
}
}
Then to use it:
TimePickerDialogCustom.TimePickerDialogOnTimeSetListenerWrapper listenerWrapper =
new TimePickerDialogCustom.TimePickerDialogOnTimeSetListenerWrapper(realListener);
// Create a new instance of DatePickerDialog and return it
TimePickerDialogCustom dialog = new TimePickerDialogCustom(
getActivity(),
listenerWrapper,
hourOfDay,
minute,
DateFormat.is24HourFormat(getActivity()));
回答8:
I faced this issue showing the timepicker twice. I have overriden the onStop() of TimePickerDialog and that solved the issue. Also you should not call super.onStop() in your overriden onStop().
@Override
public void onStop() {
//super.onStop();
Log.d(TAG, "onStop of starttime TimePickerDialog.");
}