There is a problem with both DatePickerDialog and TimePickerDialog. A user can select a date and a time with the plus or minus buttons. This works. But when the user clicks into the field, he can set a value by keyboard:
But this does not work at all. When the user types in a new value, and clicks the "OK" button, the value of the currently selected field will not be passed to the onDateSet
method. This works neither in DatePickerDialog
nor in TimePickerDialog
. Instead the user needs to click the green forward button on the keyboard to really set the value in the DatePickerDialog
. When he presses "OK" then, the value is passed, but this is a pretty idiotic usability. Nobody would do this. This is how I implement the fragments:
public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener
{
private final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
// Use the current date as the default date in the picker
final Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int day = c.get(Calendar.DAY_OF_MONTH);
// Create a new instance of DatePickerDialog and return it
return new DatePickerDialog(getActivity(), this, year, month, day);
}
@Override
public void onDateSet(DatePicker view, int year, int month, int day)
{
final Calendar calendar = Calendar.getInstance(Locale.getDefault());
calendar.set(year, month, day);
String pickedDate = dateFormat.format(calendar.getTime());
((MenuEditActivity)getActivity()).setMenuDate(pickedDate);
}
@Override
public void onCancel(DialogInterface dialog)
{
super.onCancel(dialog);
}
}
Did anybody have the same issue and already implement some quick workaround? (I'd rather not want to reimplement the whole Picker dialogs, just of this half-baked implementation).
I found a workaround for DatePickerDialog
to disable the keyboard, so the user cannot type date by keyboard. (see also [Disable keyboard input on Android TimePicker)
public class MyDatePickerDialog extends DatePickerDialog
{
public MyDatePickerDialog(Context context, OnDateSetListener listener, int year, int month, int dayOfMonth)
{
super(context, listener, year, month, dayOfMonth);
}
@NonNull
@Override
public DatePicker getDatePicker()
{
return super.getDatePicker();
}
}
in fragment....
final MyDatePickerDialog datePickerDialog = new MyDatePickerDialog(getActivity(), this, year, month, day);
datePickerDialog.getDatePicker().setDescendantFocusability(DatePicker.FOCUS_BLOCK_DESCENDANTS);
But this is not possible with TimePickerDialog
since there is no method to get the TimePicker
, so I used another workaround for time picker, thanks to Mike M.
public class TimePickerFragment extends DialogFragment implements TimePickerDialog.OnTimeSetListener
{
private TimePickerDialog timePickerDialog;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
//Default 6:00
timePickerDialog = new TimePickerDialog(getActivity(), this, 6, 0, android.text.format.DateFormat.is24HourFormat(getActivity()));
return timePickerDialog;
}
@Override
public void onStart()
{
super.onStart();
final View hourView = timePickerDialog.findViewById(Resources.getSystem().getIdentifier("hour", "id", "android"));
final View minuteView = timePickerDialog.findViewById(Resources.getSystem().getIdentifier("minute", "id", "android"));
if (hourView != null && hourView instanceof NumberPicker)
{
((NumberPicker) hourView).setDescendantFocusability(TimePicker.FOCUS_BLOCK_DESCENDANTS);
}
if (minuteView != null && minuteView instanceof NumberPicker)
{
((NumberPicker) minuteView).setDescendantFocusability(TimePicker.FOCUS_BLOCK_DESCENDANTS);
}
}
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute)
{
((MenuEditActivity) getActivity()).setRecipeTime(hourOfDay, minute);
}
@Override
public void onCancel(DialogInterface dialog)
{
super.onCancel(dialog);
}
}