Как установить пользовательский интервал минут в TimePickerDialog в Android - PullRequest
6 голосов
/ 10 октября 2011

У меня есть TimePickerDialog, работающий для установки времени, которое установлено в TextView для его отображения.Теперь мне нужна помощь, чтобы установить этот интервал минут TimePicker (внутри TimePickerDialog) на 15 минут.Я видел, что есть сообщение с 15-минутным интервалом, связанным с TimePicker, но я не знаю, как применить его к TimePickerDialog, потому что я не знаю, как использовать TimePicker, который создается внутри TimePickerDialog.Я новичок в Android и полностью потерян в этом вопросе.Заранее спасибо.

Ответы [ 4 ]

14 голосов
/ 14 ноября 2013

Используя комбинацию этого из @Rizwan и этого другого потока, я придумал комбинированное решение, которое допускает произвольные приращения минут в TimePickerDialog.Основная проблема заключается в том, что большая часть функциональности скрыта классами android TimePickerDialog и TimePicker, и это не похоже на

  1. Расширение TimePickerDialog, чтобы облегчить нам доступ
  2. Используйте отражение, чтобы попасть внутрь дисплея и получить доступ к необходимым битам (см. Ниже)
  3. перепишите минутный NumberPicker для отображения наших значений
  4. перепишите TimePicker для получения ивозвращаемые значения формируют NumberPicker, соблюдая наше пользовательское приращение.
  5. 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.

11 голосов
/ 02 апреля 2012

Хорошо, если вы используете указатель времени вместо диалогового окна выбора времени.Но есть решение для этого на самом деле ... вот то, что я использовал для удовлетворения того же требования .. Я использовал CustomTimePickerDialog.Все будет одинаково, только TimePickerDialog изменится на CustomTimePickerDialog в коде.

CustomTimePickerDialog timePickerDialog = new CustomTimePickerDialog(myActivity.this, timeSetListener, 
            Calendar.getInstance().get(Calendar.HOUR), 
            CustomTimePickerDialog.getRoundedMinute(Calendar.getInstance().get(Calendar.MINUTE) + CustomTimePickerDialog.TIME_PICKER_INTERVAL), 
            false
);
timePickerDialog.setTitle("2. Select Time");
timePickerDialog.show();

Вот мой класс CustomTimePickerDialog ... Просто используйте этот класс в своем проекте и измените TimePickerDialog на CustomTimePickerDialog ..

public class CustomTimePickerDialog extends TimePickerDialog{

    public static final int TIME_PICKER_INTERVAL=10;
    private boolean mIgnoreEvent=false;

    public CustomTimePickerDialog(Context context, OnTimeSetListener callBack, int hourOfDay, int minute,
        boolean is24HourView) {
    super(context, callBack, hourOfDay, minute, is24HourView);
    }
/*
 * (non-Javadoc)
 * @see android.app.TimePickerDialog#onTimeChanged(android.widget.TimePicker, int, int)
 * Implements Time Change Interval
 */
    @Override
    public void onTimeChanged(TimePicker timePicker, int hourOfDay, int minute) {
        super.onTimeChanged(timePicker, hourOfDay, minute);
        this.setTitle("2. Select Time");
        if (!mIgnoreEvent){
            minute = getRoundedMinute(minute);
            mIgnoreEvent=true;
            timePicker.setCurrentMinute(minute);
            mIgnoreEvent=false;
        }
    }

    public static int getRoundedMinute(int minute){
         if(minute % TIME_PICKER_INTERVAL != 0){
            int minuteFloor = minute - (minute % TIME_PICKER_INTERVAL);
            minute = minuteFloor + (minute == minuteFloor + 1 ? TIME_PICKER_INTERVAL : 0);
            if (minute == 60)  minute=0;
         }

        return minute;
    }
}

После использования этого класса CustomTimePickerDialog все, что вам нужно будет сделать, это использовать CustomTimePickerDialog вместо TimePickerDialog в вашем коде для доступа / переопределения стандартных функций класса TimePickerDialog.Проще говоря, я имею в виду, что ваш timeSetListener будет следующим после этого ...

private CustomTimePickerDialog.OnTimeSetListener timeSetListener = new CustomTimePickerDialog.OnTimeSetListener() {
    @Override
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {

    }
}// using CustomTimePickerDialog
1 голос
/ 10 октября 2011

Вы можете использовать обычный AlertDialog и использовать setView для включения пользовательского представления TimePicker.

0 голосов
/ 13 октября 2017
/**
 * Set TimePicker interval by adding a custom minutes list
 * TIME_PICKER_INTERVAL = Enter your Minutes;
 * @param timePicker
 */
private void setTimePickerInterval(TimePicker timePicker) {
    try {
        int TIME_PICKER_INTERVAL = 10;
        NumberPicker minutePicker = (NumberPicker) timePicker.findViewById(Resources.getSystem().getIdentifier(
                "minute", "id", "android"));
        minutePicker.setMinValue(0);
        minutePicker.setMaxValue((60 / TIME_PICKER_INTERVAL) - 1);
        List<String> displayedValues = new ArrayList<String>();
        for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL) {
            displayedValues.add(String.format("%02d", i));
        }
        minutePicker.setDisplayedValues(displayedValues.toArray(new String[0]));
    } catch (Exception e) {
        Log.e(TAG, "Exception: " + e);
    }
}
...