material-components-android icon indicating copy to clipboard operation
material-components-android copied to clipboard

[MaterialDatePicker] Support for selecting multiple dates

Open StefMa opened this issue 3 years ago • 0 comments
trafficstars

Is your feature request related to a problem? Please describe. Currently there is no way to use the date picker to select multiple dates. Only a single date or a date range is possible.

Describe the solution you'd like I would like to see an date picker to select multiple dates which are not a range.

Additional context We need an calendar which where users can select multiple (independend) dates. Like

I want to use this service on 2022-08-04 2022-08-10 and 2022-08-12

I found out that this is somewhat possible to implement already. Checkout this one:

https://user-images.githubusercontent.com/10229883/182604466-2bb47ac4-89b7-4978-ba6d-e5ce8958803c.mp4

(Ugly!) Kotlin source code

@SuppressLint("RestrictedApi")
class MultipleDatesSelector() : SingleDateSelector() {

    private var dates = mutableListOf<Long>()

    override fun select(selection: Long) {
        if (dates.contains(selection)) dates.remove(selection)
        else dates.add(selection)
    }

    override fun isSelectionComplete(): Boolean {
        return dates.isNotEmpty()
    }

    override fun getSelectedDays(): MutableCollection<Long> {
        return dates.toCollection(arrayListOf())
    }

    override fun getSelectionDisplayString(context: Context): String {
        return "" // TODO: A nice string for multiple dates
    }

    override fun getDefaultTitleResId(): Int {
        return R.string.select_multiple_dates_title
    }

    /* Parcelable interface */
    // TODO: Is this correcty implemented?! 
    @JvmField
    val CREATOR: Parcelable.Creator<SingleDateSelector> = object : Parcelable.Creator<SingleDateSelector> {
        override fun createFromParcel(source: Parcel): SingleDateSelector {
            val singleDateSelector = X()
            singleDateSelector.dates = source.readValue(List::class.java.classLoader) as MutableList<Long>
            return singleDateSelector
        }

        override fun newArray(size: Int): Array<SingleDateSelector> {
            return arrayOf(X())
        }
    }
}

This is possible because there exist already an method to add a custom selector. https://github.com/material-components/material-components-android/blob/a6df2545efb84e7bca37fdf987ec35c6846e5025/lib/java/com/google/android/material/datepicker/MaterialDatePicker.java#L623-L627

Unfortunately, the method above as well as the DateSelector is restricted to the Scope.LibraryGroup, which is odd. https://github.com/material-components/material-components-android/blob/a6df2545efb84e7bca37fdf987ec35c6846e5025/lib/java/com/google/android/material/datepicker/DateSelector.java#L50-L51

It would be great if to consider to either:

  • Remove the restriction
  • Support a multiple dates picker via this library

As my code shows the implementation isn't that hard. Would you interested in support such an picker? I could also help by creating a pull request for it... I would also help to cleanup the DateSelector interface instead and to remove the restriction (because I think it is restricted because the DateSelector isn't a great abstraction yeat 😁 )

Thank you.

StefMa avatar Aug 03 '22 12:08 StefMa