Tho*_*ard 23 android timepicker
我正在寻找一种方法来设置Android上的maximun和minimun时间TimePickerDialog,并将默认的分钟间隔从1分钟更改为5分钟,
我觉得这很简单,但我找不到方法!
Zar*_*kka 37
这个答案已经过时了
它不适用于Android 5或更高版本.
这是小提琴手答案的延伸.某些Android版本中的TimePickerDialog没有设置onTimeChangedListener:
因此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);
}
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*Gin 11
对于lolipop和更高版本的android,您可以使用此修改后的RangeTimePickerDialog类
(从lolipop,Timepicker默认使用时钟模式(材料设计),以便旧的自定义类不起作用.我们可以将模式更改为spinner以获取最新版本并可以重用该类)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以将此作为起点.
我扩展了TimePickerDialog并添加了2个方法setMin和setMax.
在onTimeChanged方法I中,检查新时间相对于最小/最大时间是否有效.
它仍然需要一些抛光......
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
39491 次 |
| 最近记录: |