我尝试显示具有不同类型ViewHolder(即文本、图像文本、视频等)的消息列表。我从API中获得了这些对象的列表,其格式如下:
{
"message":"success",
"total_pages":273,
"current_page":1,
"page_size":10,
"notifications":[
{
"id":4214,
"notification_message":"test notification 1",
"meta_data":{
"messageId":"19819189",
"viewHolderType":"textOnly",
"body":{
"time":"10-06-21T02:31:29,573",
"type":"notification",
"title":"Hi, Welcome to the NT experience",
"description":"This is the welcome message",
"read":true
}
}
},
{
"id":9811,
"notification_message":"test vss notification",
"meta_data":{
"messageId":"2657652",
"viewHolderType":"textWithImage",
"body":{
"time":"11-06-21T02:31:29,573",
"type":"promotions",
"title":"Your Package - Premium",
"description":"Thank you for subscribing to the package. Your subscription entitles you to Premium 365 Days Plan (worth $76.61)",
"headerImage":"www.someurl.com/image.jpg",
"read":true
}
}
}
]
}
现在我必须从网络模块中解析这个列表,以获取只使用 meta_data中的对象的客户端模块。为此,我创建了以下类:
open class BaseMessageListItem
internal data class MessageListResponse(
@field:SerializedName("current_page")
val current_page: Int,
@field:SerializedName("notifications")
val notifications: List<MessageListItem>,
@field:SerializedName("message")
val message: String,
@field:SerializedName("page_size")
val page_size: Int,
@field:SerializedName("total_page")
val total_page: Int
)
internal data class MessageListItem(
@field:SerializedName(“id”)
val id: String,
@field:SerializedName("notification_message")
val notification_message: String,
@field:SerializedName("meta_data")
val meta_data: MessageListMetaDataItem,
)
internal data class MessageListMetaDataItem(
@field:SerializedName("messageId")
val messageId: String = "",
@field:SerializedName("viewHolderType")
val viewHolderType: String = "",
@field:SerializedName("body")
val body: BaseMessageListItem = BaseMessageListItem()
)
internal data class ImageMessageListItem(
@field:SerializedName("description")
val description: String,
@field:SerializedName("headerImage")
val headerImage: String,
@field:SerializedName("read")
val read: Boolean,
@field:SerializedName("time")
val time: String,
@field:SerializedName("title")
val title: String,
@field:SerializedName("type")
val type: String
): BaseMessageListItem()
internal data class TextMessageListItem(
@field:SerializedName("description")
val description: String,
@field:SerializedName("read")
val read: Boolean,
@field:SerializedName("time")
val time: String,
@field:SerializedName("title")
val title: String,
@field:SerializedName("type")
val type: String
): BaseMessageListItem()
通知〉 meta_data〉body可以是多态的。我有一组类(用于ImageItem,ImageWithTextItem,VideoItem等),它们扩展到BaseMessageListItem。
private var runtimeTypeAdapterFactory: RuntimeTypeAdapterFactory<BaseMessageListItem> = RuntimeTypeAdapterFactory
.of(BaseMessageListItem::class.java, "viewHolderType")
.registerSubtype(ImageMessageListItem::class.java, MessageListItemTypes.TEXT_WITH_IMAGE.value)
.registerSubtype(TextMessageListItem::class.java, MessageListItemTypes.TEXT_ONLY.value)
private var gson: Gson = GsonBuilder()
.registerTypeAdapterFactory(runtimeTypeAdapterFactory)
.create()
我尝试在RuntimeTypeAdapterFactory
中使用viewHolderType
解析它,但由于它不是BaseMessageListItem
的属性,因此无法解析它。
任何一个有任何经验处理这种类型的JSON
,请分享任何指针。
2条答案
按热度按时间r1zhe5dt1#
RuntimeTypeAdapterFactory
要求将viewHolderType
字段直接放入body
对象中。为了解决此问题,您可以使用修补程序RuntimeTypeAdapterFactory
(它甚至没有作为编译后的JAR发布,而是仍然作为源代码保留在公共存储库中,可以自由修改),或者修复类层次结构以提升缺少的字段,因为它只能处理同一嵌套级别上的字段。ffx8fchx2#
我可能理解错了,但我想建议一种不同的方法。我假设你想直接从API响应中得到一个ViewHolder类型。
我建议采取两种办法:
viewHolderType
从String更改为Int,这样您就可以清楚地了解Map,然后可以直接比较它。viewHolderType
设置值,如下所示。