Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent user from selecting past time - TimePickerDialog

IMPORTANT EDIT: I've done a bit of searching and it seems that the OnTimeChangedListener doesn't fire in Android 5.0 (API 21). Gustavo's answer below will work for API 20 or lower, and API 22 which I've tested. (Source)

I would like to prevent a user from entering a time prior to the current time. I check for a valid time using the before method provided by Date. How can I prevent the dialog from accepting an invalid time within this validity check?

I have omitted excess code where I initialize the selected time (as a Date).

final Calendar mcurrentTime = Calendar.getInstance();
final int hour = mcurrentTime.get(Calendar.HOUR_OF_DAY);
final int minute = mcurrentTime.get(Calendar.MINUTE);
final TimePickerDialog mTimePicker;
mTimePicker = new TimePickerDialog(MainActivity.this, new TimePickerDialog.OnTimeSetListener() {
    @Override
    public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute) {

        //PSEUDO: Date selectedDateTime init here

        if (selectedDateTime.before(mcurrentTime.getTime())) {
            // prevent user from selecting time
        }
    }
}, hour, minute, true);//true = 24 hour time
mTimePicker.setTitle("Select Time");
mTimePicker.show(); 
like image 994
McGuile Avatar asked Dec 24 '22 17:12

McGuile


1 Answers

Here the original post.

Following answer you should add TimePickerDialog class.

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) {

    Log.d("DADADADA", "onTimeChanged");

    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);
}
}

After that, replace your TimePickerDialog for the RangeTimePickerDialog

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final Calendar mcurrentTime = Calendar.getInstance();
    final int hour = mcurrentTime.get(Calendar.HOUR_OF_DAY);
    final int minute = mcurrentTime.get(Calendar.MINUTE);
    final RangeTimePickerDialog mTimePicker;
    mTimePicker = new RangeTimePickerDialog(MainActivity.this, new TimePickerDialog.OnTimeSetListener() {
        @Override
        public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute) {

            Log.d("TAG", "inside OnTimeSetListener");

        }
    }, hour, minute, true);//true = 24 hour time
    mTimePicker.setTitle("Select Time");
    mTimePicker.setMin(hour, minute);
    mTimePicker.show();
}
}

After that, check you dialog, time doesn't pass limits, I have checked this with both setMax() or setMin() and also setting only one.

like image 71
Gustavo Morales Avatar answered Dec 27 '22 11:12

Gustavo Morales