背景:GSON,科特林,改造
我正在编写一个餐厅应用程序。在主页中,用户可以加载餐厅品牌列表。每个品牌最多可以提供3种美食类型,第一种是非空的,接下来的两种是可空的。每种美食类型都在CuisineType枚举类中。
我想做的是创建一个这样的连接字符串: cuisineType1.title + cuisineType2?.title + cuisineType3?.title =组合的Cuisines。这样可以使所有美食都显示在textView中。为此,我创建了一个帮助器类。在此帮助器类中,如果Brand的CuisineType无法映射任何枚举成员,它将显示Brand JSON的原始名称(如果发生服务器错误)。我尝试了下面注释的三个解决方案,但其中三个都不可行。非常感谢您的帮助。预先感谢!
data class Brand(
@SerializedName("id")
val id: Int,
@SerializedName("name_en")
val nameEN: String?,
@SerializedName("cuisine_1")
val cuisineType1: String,
@SerializedName("cuisine_2")
val cuisineType2: String?,
@SerializedName("cuisine_3")
val cuisineType3: String?,
/*Solution 1(not working):
val combinedCuisines = CombineCuisineHelper.combineCuisines(cuisineType1, cuisineType2, cuisineType3)
***java.lang.IllegalArgumentException: Unable to create converter for class
*/
/*Solution 2(not working):
@Transient
val combinedCuisines = CombineCuisineHelper.combineCuisines(cuisineType1, cuisineType2, cuisineType3)
***combinedCuisines = null after network call in fragment
*/
) {
/* Solution 3(not working):
val combinedCuisines: String
get() = CombineCuisineHelper.combineCuisines(cuisineType1, cuisineType2, cuisineType3)
***problem with GSON, I can only map the @SerializedName from the Cuisine enum class and will only run the illegal argument solution from the CombineCuisineHelper. For example, get hong_kong_style from the JSON brand but it will not convert to HongKongStyle and map to its title.
*/
}
//It should be a long list but I shortened it.
enum class CuisineType {
@SerializedName("chinese")
Chinese,
@SerializedName("hong_kong_style")
HongKongStyle,
@SerializedName("cantonese")
Cantonese,
val title: Double
get() {
return when (this) {
Chinese -> "中菜"
HongKongStyle -> "港式"
Cantonese -> "粵式"
}
class CombineCuisineHelper {
companion object {
fun combineCuisines(cuisineSubtype1: String, cuisineSubtype2: String?, cuisineSubtype3: String?): String {
val combinedSubtypes = ArrayList<String?>()
combinedSubtypes += try {
CuisineSubtype.valueOf(cuisineSubtype1).title
} catch (e: IllegalArgumentException) {
cuisineSubtype1
}
if (cuisineSubtype2 != null) {
combinedSubtypes += try {
CuisineSubtype.valueOf(cuisineSubtype2).title
} catch (e: IllegalArgumentException) {
cuisineSubtype2
}
}
if (cuisineSubtype3 != null) {
combinedSubtypes += try {
CuisineSubtype.valueOf(cuisineSubtype3).title
} catch (e: IllegalArgumentException) {
cuisineSubtype3
}
}
}
答案 0 :(得分:0)
第一个和第二个解决方案不好,因为初始化时数据可能未准备好。第三种解决方案是我们可以继续使用的解决方案:
val combinedCuisines: String
get() = CombineCuisineHelper.combineCuisines(cuisineType1, cuisineType2, cuisineType3)
SerializedName
对于枚举常量没有用,并且不能像您期望的那样为您工作。因此,用于枚举的valueOf
方法将找不到"hong_kong_style"
之类的文字值,并且会引发异常。
您可以在枚举类中创建自己的帮助方法,如下所示:
enum class CuisineType {
Chinese,
HongKongStyle,
Cantonese;
val title: String
get() {
return when (this) {
Chinese -> "中菜"
HongKongStyle -> "港式"
Cantonese -> "粵式"
}
}
companion object {
//Note this helper method which manually maps string values to enum constants:
fun enumValue(title: String): CuisineType = when (title) {
"chinese" -> Chinese
"hong_kong_style" -> HongKongStyle
"cantonese" -> Cantonese
else -> throw IllegalArgumentException("Unknown cuisine type $title")
}
}
}
然后使用此新方法代替枚举自身的valueOf
方法:
val combinedSubtypes = ArrayList<String?>()
combinedSubtypes += try {
CuisineType.enumValue(cuisineSubtype1).title
} catch (e: IllegalArgumentException) {
cuisineSubtype1
}
//continued...