Используя комбинацию этого из @Rizwan и этого другого потока, я придумал комбинированное решение, которое допускает произвольные приращения минут в TimePickerDialog
.Основная проблема заключается в том, что большая часть функциональности скрыта классами android TimePickerDialog
и TimePicker
, и это не похоже на
- Расширение
TimePickerDialog
, чтобы облегчить нам доступ - Используйте отражение, чтобы попасть внутрь дисплея и получить доступ к необходимым битам (см. Ниже)
- перепишите минутный NumberPicker для отображения наших значений
- перепишите
TimePicker
для получения ивозвращаемые значения формируют NumberPicker
, соблюдая наше пользовательское приращение. - block onStop () , чтобы не сбрасывать значение при закрытии.
Предупреждение
Основная проблема с охватом внутри пользовательского интерфейса заключается в том, что на элементы ссылаются идентификаторы, которые могут измениться, и даже имя идентификатора не всегда будет одинаковым.Сказав это, это работает, стабильное решение и, вероятно, будет работать в обозримом будущем.По моему мнению, пустой блок catch должен предупреждать, что пользовательский интерфейс изменился и должен вернуться к поведению по умолчанию (с шагом в 1 минуту).
Решение
private class DurationTimePickDialog extends TimePickerDialog
{
final OnTimeSetListener mCallback;
TimePicker mTimePicker;
final int increment;
public DurationTimePickDialog(Context context, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView, int increment)
{
super(context, callBack, hourOfDay, minute/increment, is24HourView);
this.mCallback = callBack;
this.increment = increment;
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (mCallback != null && mTimePicker!=null) {
mTimePicker.clearFocus();
mCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
mTimePicker.getCurrentMinute()*increment);
}
}
@Override
protected void onStop()
{
// override and do nothing
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
try
{
Class<?> rClass = Class.forName("com.android.internal.R$id");
Field timePicker = rClass.getField("timePicker");
this.mTimePicker = (TimePicker)findViewById(timePicker.getInt(null));
Field m = rClass.getField("minute");
NumberPicker mMinuteSpinner = (NumberPicker)mTimePicker.findViewById(m.getInt(null));
mMinuteSpinner.setMinValue(0);
mMinuteSpinner.setMaxValue((60/increment)-1);
List<String> displayedValues = new ArrayList<String>();
for(int i=0;i<60;i+=increment)
{
displayedValues.add(String.format("%02d", i));
}
mMinuteSpinner.setDisplayedValues(displayedValues.toArray(new String[0]));
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
конструктор принимает значение приращения и сохраняет некоторые другие ссылки.Обратите внимание, что при этом отсутствует проверка ошибок, и мы бы предпочли, чтобы 60%increment==0
onCreate использовало имя полей пользовательского интерфейса и отражения для обнаружения текущего местоположения.Опять же, это исключает проверку ошибок и должно быть «отказоустойчивым», т. Е. Возвращаться к поведению по умолчанию, если что-то пойдет не так.
onStop переопределяется, чтобы предотвратить (неверное) возвращаемое значение индекса во второй раз, когда диалоговое окно закрывается.Продолжайте, попробуйте сами.
Большая часть этого происходит от копания в источник TimePickerDialog.