Search code examples
androidmaterial-components-androiddaterangepicker

Material DateRangePicker enable Accept button with single date


I have a material daterangepicker to select a single date or a range. If i want to select a single date i must select the same date twice to enable "Accept" button. There are something to enable Accept button when select the first date?

I see in MaterialDatePicker.java that they use:

pickerFragment.addOnSelectionChangedListener(
    new OnSelectionChangedListener<S>() {
      @Override
      public void onSelectionChanged(S selection) {
        updateHeader();
        confirmButton.setEnabled(dateSelector.isSelectionComplete());
      }

      @Override
      public void onIncompleteSelectionChanged() {
        confirmButton.setEnabled(false);
      }
    });

I think i need to use this or something similar but i cant access to this method.

I use this to show DateRangePicker:

private fun showDatePicker() {
    val builder = MaterialDatePicker.Builder.dateRangePicker()
    builder.setTheme(R.style.CustomCalendarDatePickerTheme)
    builder.setCalendarConstraints(limitRange().build())

    val picker = builder.build()
    picker.addOnPositiveButtonClickListener {
        tv_date.text = formatRange(it.first!!, it.second!!)
        startDate = it.first
        endDate = it.second
    }

    picker.show(supportFragmentManager, picker.toString())
}

Solution

  • Finally I create a class that extend RangeDateSelector and overriding select() function, when is the first time I set the date in both start and end:

    @SuppressLint("RestrictedApi")
    class CustomMaterialDatePicker : RangeDateSelector() {
    
        private var first = true
        private var firstDate: Long? = null
    
        override fun select(selection: Long) {
            if (first || selection < firstDate!!) {
                super.select(selection)
                super.select(selection)
                firstDate = selection
                first = false
            } else {
                super.select(firstDate!!)
                super.select(selection)
                if (selection != firstDate) {
                    first = true
                }
            }
        }
    }
    

    And I create DateRangePicker like this:

    @SuppressLint("RestrictedApi")
    private fun showDatePicker() {
        val selector = CustomMaterialDatePicker()
        val builder = MaterialDatePicker.Builder.customDatePicker(selector)
        builder.setTheme(R.style.CustomCalendarDatePickerTheme)
        builder.setCalendarConstraints(limitRange().build())
    
        val picker = builder.build()
        picker.addOnPositiveButtonClickListener {
            tv_date.text = formatRange(it.first!!, it.second!!)
            startDate = it.first
            endDate = it.second
        }
    
        picker.show(supportFragmentManager, picker.toString())
    }