Search code examples
androidradio-buttonandroid-datepickerandroid-timepicker

How do I activate a button if the date from is within a given range and if radio button is "yes"?


I am making an Android app where I use DatePickerDialog and TimePickerDialog to get a specific time from the user and a RadioButton to know if a requirement is met. I want to activate a button if the time is larger than 3 days, less than 3 weeks and the RadioButton "yes" is checked.

I use DialogFragments to get the date and time from the user as well as to update the layout.

MainActivity:

public void showDatePickerDialog(View v) {
    DialogFragment newFragment = new DatePickerFragment();
    newFragment.show(getFragmentManager(), "datePicker");
}

public void showTimePickerDialog(View v) {
    DialogFragment newFragment = new TimePickerFragment();
    newFragment.show(getFragmentManager(), "timePicker");
}

public void onRadioButtonClicked(View v) {
    // Is the button now checked?
    boolean checked = ((RadioButton) v).isChecked();

    // Check which radio button was clicked
    switch (v.getId()) {
        case R.id.yes:
            if (checked)
                test_button.setEnabled(true);
                test_button.setAlpha(1);
            break;
        case R.id.no:
            if (checked)
                test_button.setEnabled(false);
                test_button.setAlpha(.5f);
            break;
    }
}

DatePickerFragment:

public class DatePickerFragment extends DialogFragment
    implements DatePickerDialog.OnDateSetListener {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the current date as the default date in the picker
        final Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);

        // Create a new instance of DatePickerDialog and return it
        return new DatePickerDialog(getActivity(), this, year, month, day);
    }

    public void onDateSet(DatePicker view, int year, int month, int day) {
        Calendar cal = Calendar.getInstance();
        cal.set(year, month, day);
        Log.w("DatePicker", "Date = " + year + month + year);

        // Update date in the view
        ((TextView) getActivity().findViewById(R.id.dateTextView)).setText(day + " / " + month);
    }
    ...
}

This works for the RadioButton but I can't get my head wrapped around how to include the date and time as part of the condition. Every time I change the date, time or condition it has to evaluate if the button is going to be activated or deactivated.

Any suggestions?


Solution

  • I solved it using a DatePickerFragmentListener. When the date or time is changed in the fragments onDateSet in MainActivity will update the time and date and check if it's within the interval > 4 hours and < 2 weeks. The button state will change accordingly and Toast is used if the user picked a date outside the interval or the checkbox is not checked.

    DatePickerFragment:

    public interface DatePickerFragmentListener {
        void onDateSet(Calendar cal);
    }
    
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the current date as the default date in the picker
        final Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);
    
        // Create a new instance of DatePickerDialog and return it
        // If you're alive you can't be born in the future
        DatePickerDialog dialog = new DatePickerDialog(getActivity(), this, year, month, day);
        dialog.getDatePicker().setMaxDate(System.currentTimeMillis());
        return dialog;
    }
    
    public void onDateSet(DatePicker view, int year, int month, int day) {
        Calendar cal = Calendar.getInstance();
        cal.set(year, month, day, 0, 0);
        Log.w("DatePicker", "Date = " + year + month + year);
    
        // Update date in the view
        ((TextView) getActivity().findViewById(R.id.dateTextView)).setText(
                cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.ENGLISH ) + " " + day);
    
        // Update listeners
        DatePickerFragmentListener activity = (DatePickerFragmentListener) getActivity();
        activity.onDateSet(cal);
        this.dismiss();
    }
    

    MainActivity:

    private Calendar birthDate;
    private Calendar birthDay;
    private Calendar birthTime;
    private Calendar cal4Hours;
    private Calendar cal2Weeks;
    
    @Override
    public void onDateSet(Calendar cal) {
        this.birthDay = cal;
        this.birthDay.clear(Calendar.HOUR_OF_DAY);
        this.birthDay.clear(Calendar.HOUR);
        this.birthDay.clear(Calendar.MINUTE);
        calculateBirthDate();
        updateButtonState();
    }
    
    @Override
    public void onTimeSet(Calendar cal) {
        this.birthTime = cal;
        calculateBirthDate();
        updateButtonState();
    }
    
    public void calculateBirthDate() {
        if (this.birthDay == null || this.birthTime == null) {
            // Do nothing
        } else {
            this.birthDate = (Calendar) this.birthDay.clone();
            this.birthDate.set(Calendar.HOUR_OF_DAY, this.birthTime.get(Calendar.HOUR_OF_DAY));
            this.birthDate.set(Calendar.HOUR, this.birthTime.get(Calendar.HOUR));
            this.birthDate.set(Calendar.AM_PM, this.birthTime.get(Calendar.AM_PM));
            this.birthDate.set(Calendar.MINUTE, this.birthTime.get(Calendar.MINUTE));
        }
    }
    
    public boolean isBirthDateWithinRange() {
        // Reset from and to range
        this.cal4Hours = (Calendar) birthDate.clone();
        this.cal2Weeks = (Calendar) birthDate.clone();
        cal4Hours.add(Calendar.HOUR_OF_DAY, 4);
        cal2Weeks.add(Calendar.WEEK_OF_YEAR, 2);
    
        Calendar now = Calendar.getInstance();
    
        if (now.after(cal4Hours) && now.before(cal2Weeks)) {
            return true;
        } else {
            return false;
        }
    }
    
    
    public void updateButtonState() {
        if (birthDay == null || birthTime == null || lowBirthWeight == null) {
            // do nothing
            test_button.setEnabled(false);
            test_button.setAlpha(.5f);
        } else if (!isBirthDateWithinRange()) {
                Toast.makeText(this, "Your child is too young or old to use the app",
                        Toast.LENGTH_LONG).show();
            test_button.setEnabled(false);
            test_button.setAlpha(.5f);
        } else if (lowBirthWeight == true) {
            Toast.makeText(this,
                    "The birth weight has to be more than 2.5 kg for the app to work",
                    Toast.LENGTH_LONG).show();
            test_button.setEnabled(false);
            test_button.setAlpha(.5f);
        } else {
            // Enable button
            test_button.setEnabled(true);
            test_button.setAlpha(1);
        }
    }