Home > Enterprise >  Enum of type Unit
Enum of type Unit

Time:03-04

I want to create an Enum or Sealed class that is gonna hold the values for a DropDownMenu in order to sort a list.

In my ViewModel I have

result.data.map { it.toPresentationModel() }.sortedWith(compareBy {it.date})

Instead of compareBy {it.date}) I wanna do that inside the enum/sealed class because for other options I wanna do (compareByDescending{it.date}) and just pass here the current selected value of the DropDownMenu.

And inside compareBy() I need to pass a parameter from a Data class

And also I would like to retrieve the enum's value name to put it inside my DropDownMenu

Here's how it looks like

enter image description here

Is this possible? Any suggestions please?

CodePudding user response:

You can implement functions inside of enums:

enum class SortBy(val name: String) {
    DATE("Date") {
        override fun <T : Comparable> sort(data: List<T>): List<T> { ... }
    },
    TIME("Time") {
        override fun <T : Comparable> sort(data: List<T>): List<T> { ... }
    },
    AMOUNT("Amount") {
        override fun <T : Comparable> sort(data: List<T>): List<T> { ... }
    },
    PRICE("Price") {
        override fun <T : Comparable> sort(data: List<T>): List<T> { ... }
    };

    abstract fun <T : Comparable> sort(data: List<T>): List<T>
}

Notice the semicolon after the last constant.

You can then implement it as an adapter or something.

CodePudding user response:

Your enum class can itself implement the Comparator interface so you can directly pass its instances to compareBy and other similar functions.

I don't think you should hard-code the names of the values, because it will make translations difficult. Put those names in String resources. You can perform a one-time initialization of the names once you have a Context available. You can override toString() to present this possibly translated name to make it easy to use this enum in drop-downs.

For example, given this class:

data class PresentationModel(val date: LocalDate, val price: BigInteger)

You could create this enum:

enum class PresentationSort(
    private val nameId: Int,
    compareBy: (PresentationModel)->Comparable<*>
): Comparator<PresentationModel> {
    Date(R.string.date, PresentationModel::date),
    Price(R.string.price, PresentationModel::price);

    private var resourceName: String? = null
    private val comparator = compareBy(compareBy)
    override fun compare(o1: PresentationModel?, o2: PresentationModel?): Int 
        = comparator.compare(o1, o2)

    override fun toString() = resourceName ?: name

    companion object {
        fun initialize(context: Context) {
            for (value in values()) resourceName = context.getString(value.nameId)
        }
    }
 
}

And pass it like:

result.data.map { it.toPresentationModel() }.sortedWith(PresentationSort.Date)

PresentationSort.initialize() should be called at the earliest opportunity, like at the beginning of onCreate() of the MainActivity. This will also cause it to update to the latest translation if the user changed languages while your app is open.

  • Related