studio programacion para libros gratis edición desarrollo desarrollar aprende aplicaciones android timepicker

programacion - Android TimePickerDialog establece el tiempo máximo



programacion android pdf 2018 (9)

Después del código Re-factorizado de fiddler:

public class RangeTimePickerDialog extends TimePickerDialog { private int mMinHour = -1; private int mMinMinute = -1; private int mMaxHour = 100; private int mMaxMinute = 100; private int mCurrentHour; private int mCurrentMinute; public RangeTimePickerDialog(Context context, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView) { super(context, callBack, hourOfDay, minute, is24HourView); mCurrentHour = hourOfDay; mCurrentMinute = minute; // Somehow the onTimeChangedListener is not set by TimePickerDialog // in some Android Versions, so, Adding the listener using // reflections try { Class<?> superclass = getClass().getSuperclass(); Field mTimePickerField = superclass.getDeclaredField("mTimePicker"); mTimePickerField.setAccessible(true); TimePicker mTimePicker = (TimePicker) mTimePickerField.get(this); mTimePicker.setOnTimeChangedListener(this); } catch (NoSuchFieldException e) { } catch (IllegalArgumentException e) { } catch (IllegalAccessException e) { } } public void setMin(int hour, int minute) { mMinHour = hour; mMinMinute = minute; } public void setMax(int hour, int minute) { mMaxHour = hour; mMaxMinute = minute; } @Override public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { super.onTimeChanged(view, hourOfDay, minute); boolean validTime; if (((hourOfDay < mMinHour ) || (hourOfDay == mMinHour && minute < mMinMinute)) || ((hourOfDay > mMaxHour) || (hourOfDay == mMaxHour && minute > mMaxMinute))) { validTime = false; } else { validTime = true; } if (validTime) { mCurrentHour = hourOfDay; mCurrentMinute = minute; } else { updateTime(mCurrentHour, mCurrentMinute); } } }

Estoy buscando una manera de establecer el tiempo máximo y mínimo seleccionable en un TimePickerDialog Android y cambiar el intervalo de minutos predeterminado de 1 min a 5 min.

Pensé que era fácil, ¡pero no puedo encontrar una manera!


Espero este trabajo, funciona perfectamente conmigo ...

Establecer el tiempo máximo para el selector de tiempo.

timePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() { @Override public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { if (!mIsOnTimeChanged) { mIsOnTimeChanged = true; Calendar c = Calendar.getInstance(); //get the selected day if it is before today allow AM and PM trick //else apply rules int selected_year = datePicker.getYear(); int selected_month = datePicker.getMonth(); int selected_day = datePicker.getDayOfMonth(); int today = c.get(Calendar.DAY_OF_MONTH); int year = c.get(Calendar.YEAR); int month = c.get(Calendar.MONTH); int hour = c.get(Calendar.HOUR); hour += 12; int min = c.get(Calendar.MINUTE); //Check if user enter hh | mm | more than current reset the timePicker with the current time //http://.com/questions/2659954/timepickerdialog-and-am-or-pm if ((hourOfDay == hour | hour < hourOfDay | hourOfDay > hour | hour > hourOfDay | minute > min) && (selected_month == month && selected_day == today && selected_year == year)) { int AM_PM_Value = hourOfDay; Calendar datetime = Calendar.getInstance(); int hour_without_24 = (hour - 12); if ((datetime.get(Calendar.AM_PM) == Calendar.AM) && (hourOfDay > hour_without_24)) { //set AM timePicker.setCurrentHour(hour - 12); } if (hourOfDay == (hour - 12) && minute > min) { timePicker.setCurrentMinute(min); } if (hourOfDay > hour && datetime.get(Calendar.AM_PM) != Calendar.AM) { timePicker.setCurrentHour(hour); if (minute > min) { timePicker.setCurrentMinute(min); } } } else if (selected_month != month | selected_day != today | selected_year != year) { } else if (hourOfDay == hour && minute > min) { timePicker.setCurrentMinute(min); } else if (hourOfDay > hour) { timePicker.setCurrentHour(hour); if (minute > min) { timePicker.setCurrentMinute(min); } } // isTimePickerChanged = true; String AM_PM; if (hourOfDay < 12) { AM_PM = "AM"; } else { AM_PM = "PM"; } //to set as 12 hour time_format = (hourOfDay + ":" + minute + ":" + "00"); if (hourOfDay > 12) { hourOfDay = (hourOfDay - 12); } st_time = (hourOfDay + ":" + pad(minute) + " " + AM_PM); mIsOnTimeChanged = false; } } });


Espero que esto pueda ser útil. Usé la biblioteca del tiempo de Joda.

public class RangeTimePicker extends TimePicker implements TimePicker.OnTimeChangedListener { private int mMinHour = -1; private int mMinMinute = -1; private int mMaxHour = 25; private int mMaxMinute = 61; private int mCurrentHour; private int mCurrentMinute; public RangeTimePicker(Context context) { super(context); setOnTimeChangedListener(this); } public RangeTimePicker(Context context, AttributeSet attrs) { super(context, attrs); setOnTimeChangedListener(this); } public RangeTimePicker(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setOnTimeChangedListener(this); } public void setMaxTime(int hourIn24, int minute) { mMaxHour = hourIn24; mMaxMinute = minute; LocalTime currentTime = LocalTime.now(); LocalTime maxTime = new LocalTime(mMaxHour, mMaxMinute); if (currentTime.isAfter(maxTime)) { this.setCurrentHour(mCurrentHour = currentTime.getHourOfDay()); this.setCurrentMinute( mCurrentMinute = currentTime.getMinuteOfHour()); } } public void setMinTime(int hourIn24, int minute) { mMinHour = hourIn24; mMinMinute = minute; LocalTime currentTime = LocalTime.now(); LocalTime minTime = new LocalTime(mMinHour, mMinMinute); if (currentTime.isBefore(minTime)) { this.setCurrentHour(mCurrentHour = minTime.getHourOfDay()); this.setCurrentMinute(mCurrentMinute = minTime.getMinuteOfHour()); } } @Override public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { boolean validTime = true; if (hourOfDay < mMinHour || (hourOfDay == mMinHour && minute < mMinMinute)) { validTime = false; } if (hourOfDay > mMaxHour || (hourOfDay == mMaxHour && minute > mMaxMinute)) { validTime = false; } if (validTime) { mCurrentHour = hourOfDay; mCurrentMinute = minute; } setCurrentHour(mCurrentHour); setCurrentMinute(mCurrentMinute); } }


No hay métodos nativos para establecer el tiempo máximo / mínimo, pero quizás funcione si amplía onTimeChanged o updateTime , puede evitar que el tiempo se establezca en un valor fuera de sus límites.


Para lolipop y una versión superior de Android, puede usar esta clase modificada RangeTimePickerDialog

(Desde lolipop, Timepicker usa el modo de reloj (diseño del material) como predeterminado para que la antigua clase personalizada no funcione. Podemos cambiar el modo a spinner para la última versión y reutilizar la clase)

public class RangeTimePickerDialog extends TimePickerDialog { private int minHour = -1; private int minMinute = -1; private int maxHour = 25; private int maxMinute = 25; private int currentHour = 0; private int currentMinute = 0; private Calendar calendar = Calendar.getInstance(); private DateFormat dateFormat; public RangeTimePickerDialog(Context context, int dialogTheme, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView) { super(context, callBack, hourOfDay, minute, is24HourView); currentHour = hourOfDay; currentMinute = minute; dateFormat = DateFormat.getTimeInstance(DateFormat.SHORT); fixSpinner(context, hourOfDay, minute, is24HourView); try { Class<?> superclass = getClass().getSuperclass(); Field mTimePickerField = superclass.getDeclaredField("mTimePicker"); mTimePickerField.setAccessible(true); TimePicker mTimePicker = (TimePicker) mTimePickerField.get(this); mTimePicker.setOnTimeChangedListener(this); } catch (NoSuchFieldException e) { } catch (IllegalArgumentException e) { } catch (IllegalAccessException e) { } } public void setMin(int hour, int minute) { minHour = hour; minMinute = minute; } public void setMax(int hour, int minute) { maxHour = hour; maxMinute = minute; } @Override public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { boolean validTime = true; if (hourOfDay < minHour || (hourOfDay == minHour && minute < minMinute)){ validTime = false; } if (hourOfDay > maxHour || (hourOfDay == maxHour && minute > maxMinute)){ validTime = false; } if (validTime) { currentHour = hourOfDay; currentMinute = minute; } updateTime(currentHour, currentMinute); updateDialogTitle(view, currentHour, currentMinute); } private void updateDialogTitle(TimePicker timePicker, int hourOfDay, int minute) { calendar.set(Calendar.HOUR_OF_DAY, hourOfDay); calendar.set(Calendar.MINUTE, minute); String title = dateFormat.format(calendar.getTime()); setTitle(title); } private void fixSpinner(Context context, int hourOfDay, int minute, boolean is24HourView) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // android:timePickerMode spinner and clock began in Lollipop try { // Get the theme''s android:timePickerMode //two modes are available clock mode and spinner mode ... selecting spinner mode for latest versions final int MODE_SPINNER = 2; Class<?> styleableClass = Class.forName("com.android.internal.R$styleable"); Field timePickerStyleableField = styleableClass.getField("TimePicker"); int[] timePickerStyleable = (int[]) timePickerStyleableField.get(null); final TypedArray a = context.obtainStyledAttributes(null, timePickerStyleable, android.R.attr.timePickerStyle, 0); Field timePickerModeStyleableField = styleableClass.getField("TimePicker_timePickerMode"); int timePickerModeStyleable = timePickerModeStyleableField.getInt(null); final int mode = a.getInt(timePickerModeStyleable, MODE_SPINNER); a.recycle(); if (mode == MODE_SPINNER) { TimePicker timePicker = (TimePicker) findField(TimePickerDialog.class, TimePicker.class, "mTimePicker").get(this); Class<?> delegateClass = Class.forName("android.widget.TimePicker$TimePickerDelegate"); Field delegateField = findField(TimePicker.class, delegateClass, "mDelegate"); Object delegate = delegateField.get(timePicker); Class<?> spinnerDelegateClass; if (Build.VERSION.SDK_INT != Build.VERSION_CODES.LOLLIPOP) { spinnerDelegateClass = Class.forName("android.widget.TimePickerSpinnerDelegate"); } else { spinnerDelegateClass = Class.forName("android.widget.TimePickerClockDelegate"); } if (delegate.getClass() != spinnerDelegateClass) { delegateField.set(timePicker, null); // throw out the TimePickerClockDelegate! timePicker.removeAllViews(); // remove the TimePickerClockDelegate views Constructor spinnerDelegateConstructor = spinnerDelegateClass.getConstructor(TimePicker.class, Context.class, AttributeSet.class, int.class, int.class); spinnerDelegateConstructor.setAccessible(true); // Instantiate a TimePickerSpinnerDelegate delegate = spinnerDelegateConstructor.newInstance(timePicker, context, null, android.R.attr.timePickerStyle, 0); delegateField.set(timePicker, delegate); // set the TimePicker.mDelegate to the spinner delegate // Set up the TimePicker again, with the TimePickerSpinnerDelegate timePicker.setIs24HourView(is24HourView); timePicker.setCurrentHour(hourOfDay); timePicker.setCurrentMinute(minute); timePicker.setOnTimeChangedListener(this); } } } catch (Exception e) { throw new RuntimeException(e); } } } private static Field findField(Class objectClass, Class fieldClass, String expectedName) { try { Field field = objectClass.getDeclaredField(expectedName); field.setAccessible(true); return field; } catch (NoSuchFieldException e) {} // ignore // search for it if it wasn''t found under the expected ivar name for (Field searchField : objectClass.getDeclaredFields()) { if (searchField.getType() == fieldClass) { searchField.setAccessible(true); return searchField; } } return null; } }


Puedes usar esto como punto de partida.

Extendí TimePickerDialog y agregué 2 métodos setMin y setMax .

En el método onTimeChanged compruebo que la nueva hora es válida con respecto a los tiempos mínimo / máximo.

Todavía necesita un poco de pulido ...

public class BoundTimePickerDialog extends TimePickerDialog { private int minHour = -1, minMinute = -1, maxHour = 100, maxMinute = 100; private int currentHour, currentMinute; public BoundTimePickerDialog(Context context, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView) { super(context, callBack, hourOfDay, minute, is24HourView); } public void setMin(int hour, int minute) { minHour = hour; minMinute = minute; } public void setMax(int hour, int minute) { maxHour = hour; maxMinute = minute; } @Override public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { super.onTimeChanged(view, hourOfDay, minute); boolean validTime; if(hourOfDay < minHour) { validTime = false; } else if(hourOfDay == minHour) { validTime = minute >= minMinute; } else if(hourOfDay == maxHour) { validTime = minute <= maxMinute; } else { validTime = true; } if(validTime) { currentHour = hourOfDay; currentMinute = minute; } else { updateTime(currentHour, currentMinute); } } }


Solo puede usar un TimePicker personalizado con reflejar para establecer los valores.

@Override protected void onAttachedToWindow() { super.onAttachedToWindow(); try { Class<?> classForid = Class.forName("com.android.internal.R$id"); Field field = classForid.getField("minute"); NumberPicker mMinuteSpinner = (NumberPicker) findViewById(field.getInt(null)); mMinuteSpinner.setMinValue(5); mMinuteSpinner.setMaxValue((60 / timeInterval) - 1); List<String> displayedValues = new ArrayList<>(); for (int i = 0; i < 60; i += timeInterval) displayedValues.add(String.format("%02d", i)); mMinuteSpinner.setDisplayedValues(displayedValues.toArray(new String[0])); mMinuteSpinner.setWrapSelectorWheel(true); } catch (Exception e) { e.printStackTrace(); } }

Para que pueda establecer qué valores desea


Tomé la solución de @Zarooka como punto de partida. Aunque creo que encontré un error. Si tenía una hora de inicio que ya estaba fuera de rango, no podría moverla más porque se estaba rechazando cualquier "onChanged". Es por eso que extendí setMax y setMin para ir a un rango válido al configurar los minutos / máximos.

package de.appdream.garooda.view; import java.util.Calendar; import java.util.Date; import android.app.TimePickerDialog; import android.content.Context; import android.text.format.DateFormat; import android.widget.TimePicker; import java.lang.reflect.Field; public class GaroodaTimePickerDialog extends TimePickerDialog { private int minHour = -1; private int minMinute = -1; private int maxHour = 25; private int maxMinute = 61; private int currentHour = 0; private int currentMinute = 0; private Calendar calendar = Calendar.getInstance(); //private DateFormat dateFormat; public GaroodaTimePickerDialog(Context context, OnTimeSetListener callBack, int hour, int minute, boolean is24HourView) { super(context, callBack, hour, minute, is24HourView); currentHour = hour; currentMinute = minute; //dateFormat = DateFormat.getTimeInstance(DateFormat.SHORT); try { Class<?> superclass = getClass().getSuperclass(); Field mTimePickerField = superclass.getDeclaredField("mTimePicker"); mTimePickerField.setAccessible(true); TimePicker mTimePicker = (TimePicker) mTimePickerField.get(this); mTimePicker.setOnTimeChangedListener(this); } catch (NoSuchFieldException e) { } catch (IllegalArgumentException e) { } catch (IllegalAccessException e) { } } public void setMin(int hour, int minute) { minHour = hour; minMinute = minute; Calendar min = Calendar.getInstance(); Calendar existing = Calendar.getInstance(); min.set(Calendar.HOUR_OF_DAY, minHour); min.set(Calendar.MINUTE, minMinute); existing.set(Calendar.HOUR_OF_DAY, currentHour); existing.set(Calendar.MINUTE, currentMinute); if (existing.before(min)) { currentHour = minHour; currentMinute = minMinute; updateTime(currentHour, currentMinute); } } public void setMax(int hour, int minute) { maxHour = hour; maxMinute = minute; Calendar max = Calendar.getInstance(); Calendar existing = Calendar.getInstance(); max.set(Calendar.HOUR_OF_DAY, maxHour); max.set(Calendar.MINUTE, maxMinute); existing.set(Calendar.HOUR_OF_DAY, currentHour); existing.set(Calendar.MINUTE, currentMinute); if (existing.after(max)) { currentHour = maxHour; currentMinute = maxMinute; updateTime(currentHour, currentMinute); } } @Override public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { boolean validTime = true; if (hourOfDay < minHour || (hourOfDay == minHour && minute < minMinute)){ validTime = false; } if (hourOfDay > maxHour || (hourOfDay == maxHour && minute > maxMinute)){ validTime = false; } if (validTime) { currentHour = hourOfDay; currentMinute = minute; } updateTime(currentHour, currentMinute); updateDialogTitle(view, currentHour, currentMinute); } private void updateDialogTitle(TimePicker timePicker, int hourOfDay, int minute) { calendar.set(Calendar.HOUR_OF_DAY, hourOfDay); calendar.set(Calendar.MINUTE, minute); //String title = dateFormat.format(calendar.getTime()); //setTitle(title); } }


Esta respuesta es obsoleta

No funcionará en Android 5 o superior.

Esta es una extensión a la respuesta de los violinistas. De alguna manera, el onTimeChangedListener no está configurado por TimePickerDialog en algunas versiones de Android:

ex. http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.2.1_r1.2/android/app/TimePickerDialog.java

¡El método onTimeChanged para eso nunca se llama! La mejor solución para este problema actualmente, es probablemente codificar un TimePickerDialog personalizado con la lógica min / max de fiddler.

El trabajo más feo alrededor es este. (Agregando el oyente usando reflexiones) También actualizo el título para mostrar la hora seleccionada actualmente.

package com.mysuger.android.dialogs; import java.lang.reflect.Field; import java.text.DateFormat; import java.util.Calendar; import android.app.TimePickerDialog; import android.content.Context; import android.widget.TimePicker; /** * A time dialog that allows setting a min and max time. * */ public class RangeTimePickerDialog extends TimePickerDialog { private int minHour = -1; private int minMinute = -1; private int maxHour = 25; private int maxMinute = 25; private int currentHour = 0; private int currentMinute = 0; private Calendar calendar = Calendar.getInstance(); private DateFormat dateFormat; public RangeTimePickerDialog(Context context, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView) { super(context, callBack, hourOfDay, minute, is24HourView); currentHour = hourOfDay; currentMinute = minute; dateFormat = DateFormat.getTimeInstance(DateFormat.SHORT); try { Class<?> superclass = getClass().getSuperclass(); Field mTimePickerField = superclass.getDeclaredField("mTimePicker"); mTimePickerField.setAccessible(true); TimePicker mTimePicker = (TimePicker) mTimePickerField.get(this); mTimePicker.setOnTimeChangedListener(this); } catch (NoSuchFieldException e) { } catch (IllegalArgumentException e) { } catch (IllegalAccessException e) { } } public void setMin(int hour, int minute) { minHour = hour; minMinute = minute; } public void setMax(int hour, int minute) { maxHour = hour; maxMinute = minute; } @Override public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { boolean validTime = true; if (hourOfDay < minHour || (hourOfDay == minHour && minute < minMinute)){ validTime = false; } if (hourOfDay > maxHour || (hourOfDay == maxHour && minute > maxMinute)){ validTime = false; } if (validTime) { currentHour = hourOfDay; currentMinute = minute; } updateTime(currentHour, currentMinute); updateDialogTitle(view, currentHour, currentMinute); } private void updateDialogTitle(TimePicker timePicker, int hourOfDay, int minute) { calendar.set(Calendar.HOUR_OF_DAY, hourOfDay); calendar.set(Calendar.MINUTE, minute); String title = dateFormat.format(calendar.getTime()); setTitle(title); } }