Mon application affiche un TimePickerDialog pour définir une heure .. Je veux que timePickerDialog affiche les minutes avec un intervalle de 5 minutes.
Cela fonctionne bien avec ce code:
private final int TIME_PICKER_INTERVAL=5;
private boolean mIgnoreEvent=false;
…
public TimePickerDialogs(Context arg0, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView) {
super(arg0, callBack, hourOfDay, minute, is24HourView);
formato=Statics.formato;
}
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
//super.onTimeChanged(arg0, arg1, arg2);
if (mIgnoreEvent)
return;
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;
mIgnoreEvent=true;
view.setCurrentMinute(minute);
mIgnoreEvent=false;
}
}
Bien que seules les minutes puissent être sélectionnées avec un intervalle de cinq minutes, le timepickerdialog ressemble à ceci:
je ne sais pas comment les minutes montrent également la plage de 5 minutes, comme dans cette image:
J'ai cherché mais je ne trouve pas la solution.
Utilisez ce qui suit la classe personnalisée appelée CustomTimePickerDialog
, qui, je pense, résoudra votre problème.
import Java.lang.reflect.Field;
import Java.util.ArrayList;
import Java.util.List;
import Android.app.TimePickerDialog;
import Android.content.Context;
import Android.content.DialogInterface;
import Android.widget.NumberPicker;
import Android.widget.TimePicker;
public class CustomTimePickerDialog extends TimePickerDialog {
private final static int TIME_PICKER_INTERVAL = 5;
private TimePicker mTimePicker;
private final OnTimeSetListener mTimeSetListener;
public CustomTimePickerDialog(Context context, OnTimeSetListener listener,
int hourOfDay, int minute, boolean is24HourView) {
super(context, TimePickerDialog.THEME_HOLO_LIGHT, null, hourOfDay,
minute / TIME_PICKER_INTERVAL, is24HourView);
mTimeSetListener = listener;
}
@Override
public void updateTime(int hourOfDay, int minuteOfHour) {
mTimePicker.setCurrentHour(hourOfDay);
mTimePicker.setCurrentMinute(minuteOfHour / TIME_PICKER_INTERVAL);
}
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case BUTTON_POSITIVE:
if (mTimeSetListener != null) {
mTimeSetListener.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
mTimePicker.getCurrentMinute() * TIME_PICKER_INTERVAL);
}
break;
case BUTTON_NEGATIVE:
cancel();
break;
}
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
try {
Class<?> classForid = Class.forName("com.Android.internal.R$id");
Field timePickerField = classForid.getField("timePicker");
mTimePicker = (TimePicker) findViewById(timePickerField.getInt(null));
Field field = classForid.getField("minute");
NumberPicker minuteSpinner = (NumberPicker) mTimePicker
.findViewById(field.getInt(null));
minuteSpinner.setMinValue(0);
minuteSpinner.setMaxValue((60 / TIME_PICKER_INTERVAL) - 1);
List<String> displayedValues = new ArrayList<>();
for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL) {
displayedValues.add(String.format("%02d", i));
}
minuteSpinner.setDisplayedValues(displayedValues
.toArray(new String[displayedValues.size()]));
} catch (Exception e) {
e.printStackTrace();
}
}
}
Voici la capture d'écran de démonstration.
Il y a cette bibliothèque géniale MaterialDateTimePicker qui crée de superbes timepickers de matériaux stylés.
Vous pouvez utiliser l'une des méthodes suivantes pour définir votre intervalle:
setSelectableTimes (Timepoint [] times) Vous pouvez transmettre un tableau de points de temps. Ces valeurs sont les seules sélections valides dans le sélecteur . setMinTime (heure du point horaire) et setMaxTime (heure du point horaire) poursuivront couper cette liste.
setTimeInterval (int hourInterval, int minuteInterval, int secondInterval) Définit l'intervalle des heures sélectionnables dans le TimePickerDialog. Ceci est un emballage pratique setSelectableTimes
Comme @ anddev84 l'a dit, vous pouvez le faire avec votre propre TimePickerDialog personnalisé.
Cependant, jetez un coup d'œil au code source que vous pouvez trouver:
Reportez-vous au code de NumberPicker , vous y trouverez une méthode publique setDisplayedValues (String [] shownValues)
/**
* Sets the values to be displayed.
*
* @param displayedValues The displayed values.
*/
public void setDisplayedValues(String[] displayedValues)
Donc, avec ces informations, je suppose que vous pouvez simplement personnaliser votre propre dialogue de sélecteur d’heure avec un nombre de minutes limité.
/**
* Set TimePicker interval by adding a custom minutes list
*
* @param timePicker
*/
private void setTimePickerInterval(TimePicker timePicker) {
try {
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);
}
}
Lutté avec un intervalle de 30 minutes de plus que l'heure. Peut-être plus en peine si je ne voyais pas le commentaire de @Lee. Il suffit donc de poster un code complet de dialogue avec un intervalle de 30 minutes:
public class IntervalTimePickerDialog extends TimePickerDialog {
private static final String TAG = "IntervalPickerDialog";
private final static int TIME_PICKER_INTERVAL = 30;
private TimePicker timePicker;
private final OnTimeSetListener callback;
private int lastHour = -1;
private int lastMinute = -1;
public IntervalTimePickerDialog(Context context, int themeId, OnTimeSetListener callBack,
int hourOfDay, int minute, boolean is24HourView) {
super(context, themeId, callBack, hourOfDay, minute / TIME_PICKER_INTERVAL,
is24HourView);
lastHour = hourOfDay;
lastMinute = minute;
this.callback = callBack;
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (callback != null && timePicker != null) {
timePicker.clearFocus();
callback.onTimeSet(timePicker, timePicker.getCurrentHour(),
timePicker.getCurrentMinute() * TIME_PICKER_INTERVAL);
}
}
@Override
protected void onStop() {
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
try {
Class<?> classForid = Class.forName("com.Android.internal.R$id");
Field timePickerField = classForid.getField("timePicker");
this.timePicker = (TimePicker) findViewById(timePickerField.getInt(null));
Field field = classForid.getField("minute");
NumberPicker mMinuteSpinner = (NumberPicker) timePicker.findViewById(field.getInt(null));
mMinuteSpinner.setMinValue(0);
mMinuteSpinner.setMaxValue((60 / TIME_PICKER_INTERVAL) - 1);
List<String> displayedValues = new ArrayList<>();
for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL) {
displayedValues.add(String.format("%02d", i));
}
mMinuteSpinner.setDisplayedValues(displayedValues.toArray(new String[0]));
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
super.onTimeChanged(view, hourOfDay, minute);
if (lastHour != hourOfDay && lastMinute != minute) {
view.setCurrentHour(lastHour);
lastMinute = minute;
} else {
lastHour = hourOfDay;
lastMinute = minute;
}
}
En regardant le code pour TimePickerDialog
, il ne semble pas qu'ils vous donnent un moyen de modifier directement la TimePicker
avant qu'elle ne soit montrée à l'utilisateur et que vous voyez les "mauvaises minutes" que vous voyez dans l'image. Voir TimePickerDialog.Java
Ma recommandation est de créer votre propre TimePickerDialog, en vous basant sur le design d'Android. Cela peut paraître intimidant au début, mais
TimePicker
à afficher pour les minutes (comme mentionné ici ), J'ai ajouté un complément à l'excellente réponse acceptée ci-dessus. Le problème, c’est que, dans au moins certaines versions d’Android, lorsque vous modifiez l’heure sélectionnée, le titre de la boîte de dialogue sera remplacé par une valeur de temps incorrecte. Vous ne pouvez pas remplacer la méthode incriminée, updateTitle (), mais vous pouvez intercepter l'appel à onTimeChanged () et ne pas appeler super ou l'appeler avec des arguments fixes.
J'ai précisé si la méthode setTitle () avait été appelée avec un ID de chaîne différent de zéro, mais vous pouviez simplement avoir un getter/setter pour le booléen lui-même ou autre chose.
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute)
{
if (autoTitle)
{
// Super will call a private updateTitle() method, so lets make
// sure it has the right minute value.
super.onTimeChanged(view, hourOfDay, minute * TIME_PICKER_INTERVAL);
}
else
{
// do nothing
}
}
@Override
public void setTitle(int id)
{
super.setTitle(id);
autoTitle = (id == 0);
}
...
private boolean autoTitle = true;
La réponse ci-dessus fonctionne très bien avec l'ancienne version d'Android, mais cela ne fonctionnait pas pour moi dans Android 7 Nougat. En gros, le sélecteur de date est complètement modifié pour utiliser le mode Horloge ... Je fusionne en quelque sorte le code proposé ici avec https://Gist.github.com/jeffdgr8/6bc5f990bf0c13a7334ce385d482af9f , puis, il a défini par défaut le mode de TimePickerDialog pour afficher les contrôles Spinner et n'exécute le code que pour afficher les intervalles de 15 minutes dans mon cas.
Le code est affiché ici https://Gist.github.com/smaugho/14dae83f3284fa05455ee0a9e4f13099
public class CustomTimePickerDialog extends TimePickerDialog {
private final static int TIME_PICKER_INTERVAL = 15;
private TimePicker timePicker;
private final OnTimeSetListener callback;
public HorekoTimePicker(Context context,
OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView) {
super(context, callBack, hourOfDay, minute/TIME_PICKER_INTERVAL, is24HourView);
this.callback = callBack;
fixSpinner(context, hourOfDay, minute, is24HourView);
}
/**
* Workaround for this bug: https://code.google.com/p/Android/issues/detail?id=222208
* In Android 7.0 Nougat, spinner mode for the TimePicker in TimePickerDialog is
* incorrectly displayed as clock, even when the theme specifies otherwise, such as:
*
* <resources>
* <style name="Theme.MyApp" parent="Theme.AppCompat.Light.NoActionBar">
* <item name="Android:timePickerStyle">@style/Widget.MyApp.TimePicker</item>
* </style>
*
* <style name="Widget.MyApp.TimePicker" parent="Android:Widget.Material.TimePicker">
* <item name="Android:timePickerMode">spinner</item>
* </style>
* </resources>
*
* May also pass TimePickerDialog.THEME_HOLO_LIGHT as an argument to the constructor,
* as this theme has the TimePickerMode set to spinner.
*
* Taken from: https://Gist.github.com/jeffdgr8/6bc5f990bf0c13a7334ce385d482af9f
*/
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
final int MODE_SPINNER = 1;
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) 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 {
// TimePickerSpinnerDelegate was initially misnamed TimePickerClockDelegate in API 21!
spinnerDelegateClass = Class.forName("Android.widget.TimePickerClockDelegate");
}
// In 7.0 Nougat for some reason the timePickerMode is ignored and the delegate is 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);
}
setTimeIntervals();
}
} 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;
}
@Override
protected void onStop() { }
/*
* Feature #363: (Un)availability times in 15min interval
* https://abix.webhop.net/redmine/issues/363
* Solution extracted from
* http://stackoverflow.com/questions/20214547/show-timepicker-with-minutes-intervals-in-Android
*/
@Override
public void onClick(DialogInterface dialog, int which) {
super.onClick(dialog, which);
if (callback != null && timePicker != null) {
timePicker.clearFocus();
callback.onTimeSet(timePicker, timePicker.getCurrentHour(),
timePicker.getCurrentMinute()*TIME_PICKER_INTERVAL);
}
}
private void setTimeIntervals() {
try {
Class<?> classForid = Class.forName("com.Android.internal.R$id");
Field field = classForid.getField("minute");
NumberPicker mMinuteSpinner = (NumberPicker) timePicker.findViewById(field.getInt(null));
mMinuteSpinner.setMinValue(0);
mMinuteSpinner.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));
}
mMinuteSpinner.setDisplayedValues(displayedValues.toArray(new String[0]));
} catch (Exception e) {
e.printStackTrace();
}
}
}