Issue
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
Is this possible? Any suggestions please?
Solution
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<*>,
isDescending: Boolean = false
): Comparator<PresentationModel> {
Date(R.string.date, PresentationModel::date),
DateDescending(R.string.date, PresentationModel::date, true),
Price(R.string.price, PresentationModel::price);
private var resourceName: String? = null
private val comparator = if(isDescending) compareByDescending(compareBy) else 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.
Answered By - Tenfour04

0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.