Search code examples
androidandroid-datepicker

setMinDate of a DatePicker from another DatePicker


I'm developing an app for a hotel (personal learning project). In the "Book Now" page I'm displaying 2 EditText fields. One for Check-in Date and another for Check-Out Date.

I've set the DatePicker to only display current and future dates using the setMinDate(). But what I want is that the Check-out DatePicker should display (Check-in Date + 1) as selectable dates.

So for example, if the user selects the check-in date as 24/10/2017, the check-out DatePicker should display the dates from 25/10/2017.

BookFragment.java

public void onStart() {
    super.onStart();

    EditText inDate = v.findViewById(R.id.checkInDate);
    inDate.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            DateDialog dialog = new DateDialog(view);
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            dialog.show(ft, "Select Check-In Date");
        }
    });

    EditText outDate = v.findViewById(R.id.checkOutDate);
    outDate.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            EditText inDateText = v.findViewById(R.id.checkInDate);
            if (TextUtils.isEmpty(inDateText.getText().toString())) {
                Toast.makeText(getContext(), "Select Check-in Date first", Toast.LENGTH_SHORT).show();
            } else {
                DateDialog dialog = new DateDialog(view);
                FragmentTransaction ft = getFragmentManager().beginTransaction();
                dialog.show(ft, "Select Check-Out Date");
            }
        }
    });

}

DateDialog.java

@SuppressLint("ValidFragment")
public class DateDialog extends DialogFragment implements DatePickerDialog.OnDateSetListener {

EditText dateText;
int cyear, cmonth, cday;

public DateDialog(View view) {
    dateText = (EditText) view;
}

@NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {

    DatePickerDialog date = new DatePickerDialog(getActivity(), this, cyear, cmonth, cday);
    final Calendar c = Calendar.getInstance();
    Date currentDate = c.getTime();
    cyear = c.get(Calendar.YEAR);
    cmonth = c.get(Calendar.MONTH);
    cday = c.get(Calendar.DAY_OF_MONTH);
    date.getDatePicker().setMinDate(currentDate.getTime());
    return date;

}

public void onDateSet(DatePicker view, int year, int month, int day) {
    String date = day + "/" + (month + 1) + "/" + year;
    dateText.setText(date);
}

book.xml

<EditText
        android:id="@+id/checkInDate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:focusable="false"
        android:hint="@string/check_in_date"
        android:inputType="date" />

    <EditText
        android:id="@+id/checkOutDate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:focusable="false"
        android:hint="@string/check_out_date"
        android:inputType="date" />

Since both the EditText are calling the same DateDialog class, how can I get the check-in date and use it to setMinDate() for check-out?

Right now, what I'm doing as a workaround is getting the date string from EditText, parsing it into a Date and doing the same for check-out. When the user clicks the "Book" button, it checks whether the check-out is earlier than check-in using

if (odate.before(idate)) {
        outDateText.setError("Check-Out must be after Check-In");
        Toast.makeText(getContext(), "Check-Out Date must be after Check-In Date", Toast.LENGTH_SHORT).show();
        flag = 1;
    }

This does the work, but I would rather have disabled dates which are before check-in date.


Solution

  • Let your Date is

    String string_date = "24/10/2017";
    

    then, increase one day to your current date

    Calendar cal = Calendar.getInstance(); 
    cal.setTime(string_date); 
    cal.add(Calendar.DATE, 1);
    checkOutDate = cal.getTimeInMillis();
    

    then set minDate to your datePicker

    datePicker.setMinDate(checkOutDate - 1000);
    

    EDIT

    create a global long variable dateToSet in your DateDialog class

    like - long dateToSet;

    change your constructor from

    public DateDialog(View view) {
    dateText = (EditText) view;
    }
    

    to

    public DateDialog(View view, long dateToSet) {
    dateText = (EditText) view;
    //then update the value of dateToSet here
    this.dateToSet = dateToSet
    }
    

    then for your Editext 1 use this

    else {
                Date currentDate = c.getTime();
                cyear = c.get(Calendar.YEAR);
                cmonth = c.get(Calendar.MONTH);
                cday = c.get(Calendar.DAY_OF_MONTH);
                DateDialog dialog = new DateDialog(view,currentDate.getTime());
                FragmentTransaction ft = getFragmentManager().beginTransaction();
                dialog.show(ft, "Select Check-Out Date");
            }
    

    for your Editext 2 use this

    //String string_date = "24/10/2017";
    //getting current date from editText 1
    String string_date = editText.getText().toString();
    //check the string must not be null
    //then, increase one day to your current date
    
    Calendar cal = Calendar.getInstance(); 
    cal.setTime(string_date); 
    cal.add(Calendar.DATE, 1);
    checkOutDate = cal.getTimeInMillis();
    DateDialog dialog = new DateDialog(view,checkOutDate);
    FragmentTransaction ft = getFragmentManager().beginTransaction();
                dialog.show(ft, "Select Check-Out Date");
    

    Then your onCreateDialog must be

    public Dialog onCreateDialog(Bundle savedInstanceState) {
    
    DatePickerDialog date = new DatePickerDialog(getActivity(), this, cyear, cmonth, cday);
    final Calendar c = Calendar.getInstance();
    date.getDatePicker().setMinDate(dateToSet);
    return date;
    
    }
    

    may help you