我正在寻找一种方法来设置Android TimePickerDialog
上的maximun和minimun时间选择,并将默认的分钟间隔从1分钟更改为5分钟,
我觉得这很简单,但我找不到办法!
答案 0 :(得分:35)
这个答案已经过时
它不适用于Android 5或更高版本。
这是小提琴手答案的延伸。 不知何故,onTimeChangedListener在某些Android版本中没有被TimePickerDialog设置:
永远不会调用onTimeChanged方法! 目前这个问题的最佳解决方案是使用来自fiddler的min / max逻辑编写自定义TimePickerDialog。
更难看的是这个。 (使用反射添加侦听器) 我还会更新标题以显示当前选定的时间。
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);
}
}
答案 1 :(得分:8)
对于lolipop及更高版本的android,你可以使用这个修改过的RangeTimePickerDialog类
(从lolipop,Timepicker默认使用时钟模式(材料设计),以便旧的自定义类不起作用。我们可以将模式更改为spinner以获取最新版本并可以重用该类)
['1', [('2', '100')]]
['3', [('4', '300')], [('5', '400')], [('6', '500')]]
['7', [('8', '700')], [('9', '800')]]
答案 2 :(得分:5)
您可以将此作为起点。
我扩展了TimePickerDialog并添加了2个方法setMin
和setMax
。
在onTimeChanged
方法中,我检查新时间相对于最小/最大时间是否有效。
它仍然需要一些抛光......
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);
}
}
}
答案 3 :(得分:2)
重新考虑了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);
}
}
}
答案 4 :(得分:1)
没有本地方法来设置最大/最小时间,但是如果扩展onTimeChanged
或updateTime
,它可能会起作用,可以防止将时间设置为超出边界的值。
答案 5 :(得分:1)
您可以使用带反射的自定义TimePicker来设置值。
@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();
}
}
所以你可以设置你想要的值
答案 6 :(得分:0)
希望这可能会有所帮助。我使用了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);
}
}
答案 7 :(得分:0)
希望这项工作能与我完美配合......
设置时间选择器的最长时间。
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://stackoverflow.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;
}
}
});
答案 8 :(得分:-1)
我把@Zarooka的解决方案作为起点。 我想我发现了一个bug。如果你的开始时间已经超出范围,那么你就不能再移动了,因为任何“onChanged”都被拒绝了。 这就是我在设置分钟/最大值时扩展setMax和setMin以便进入有效范围的原因。
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);
}
}