JSON 序列化/反序列化 Kotlin Android Jetpack Compose Table
JSON Serialization / Deserialization Kotlin Android Jetpack Compose Table
我正在 Jetpack Compose 中创建一个 table 部分,用于反序列化来自 JSON.
的数据
此时,我只是尝试显示数据(table 格式化和清理将在稍后进行,因此您可以忽略该部分)。在我到达 table 行值是数组数组的部分之前,事情一直很顺利。我收到此错误:
错误:
Expected class kotlinx.serialization.json.JsonObject as the serialized body of ...TableRow, but had class kotlinx.serialization.json.JsonArray
这是正在为此 table 解析的测试 JSON 的部分:
{
"title": "TRANSACTION HISTORY",
"type": "Table",
"names": [
"Date",
"Amount",
"Lender",
"Borrower"
],
"values": [
[
"07\/01\/2014",
"5,000",
"Steve's Lending Co.",
"Glenn Danzig"
],
[
"10\/13\/2011",
"6,000",
"Feet Company",
"Marcus Toeswater"
]
]
},
{
"title": "ASSESSMENT & TAX",
"type": "Table",
"names": [
"Year",
"Property Taxes",
"Tax Assessment"
],
"values": [
[
"2017",
",068",
"5,000"
],
[
"2016",
",864",
"2,000"
],
[
"2015",
",609",
"1,500"
]
]
},
这是我现在拥有的代码。我只是想 post 两行数据:
1 列 header 名称,以及
1 包含所有行数据(此时不必看起来很漂亮 - 我只是想完成映射)
@Serializable
@SerialName("Table")
@Parcelize
data class TableSection(
override val title: String? = null,
@SerialName("names")
val columnHeader: ArrayList<String?> = arrayListOf(),
@SerialName("values")
val tableData: ArrayList<TableRow> = arrayListOf(),
) : Section() {
@Composable
override fun Content(modifier: Modifier) {
return Column {
Row {
columnHeader.map {
Text(it ?: "")
}
}
Row {
tableData.map { row ->
row.tableRowValues.map { value ->
Text(value ?: "")
}
}
}
}
}
}
@Serializable
@Parcelize
data class TableRow(
@Serializable
val tableRowValues: ArrayList<String?> = arrayListOf(),
) : Parcelable
注意:标题和 Table 列 Headers 工作正常。引发错误的是 table 数据。
我最终创建了一个自定义序列化程序来获取嵌套值:
@Serializable(with = TableRowSerializer::class)
@Parcelize
data class TableRow(
val tableRowValues: List<String?> = arrayListOf(),
) : Parcelable
object TableRowSerializer : KSerializer<TableRow> {
private val serializer = ListSerializer(String.serializer())
override val descriptor: SerialDescriptor = serializer.descriptor
override fun serialize(encoder: Encoder, value: TableRow) {
val rowValues = value.tableRowValues
rowValues.let{rowValues as? List<String>}
?.let { encoder.encodeSerializableValue(serializer, it) }
}
override fun deserialize(decoder: Decoder): TableRow {
return TableRow(decoder.decodeSerializableValue(serializer))
}
}
我正在 Jetpack Compose 中创建一个 table 部分,用于反序列化来自 JSON.
的数据此时,我只是尝试显示数据(table 格式化和清理将在稍后进行,因此您可以忽略该部分)。在我到达 table 行值是数组数组的部分之前,事情一直很顺利。我收到此错误:
错误:
Expected class kotlinx.serialization.json.JsonObject as the serialized body of ...TableRow, but had class kotlinx.serialization.json.JsonArray
这是正在为此 table 解析的测试 JSON 的部分:
{
"title": "TRANSACTION HISTORY",
"type": "Table",
"names": [
"Date",
"Amount",
"Lender",
"Borrower"
],
"values": [
[
"07\/01\/2014",
"5,000",
"Steve's Lending Co.",
"Glenn Danzig"
],
[
"10\/13\/2011",
"6,000",
"Feet Company",
"Marcus Toeswater"
]
]
},
{
"title": "ASSESSMENT & TAX",
"type": "Table",
"names": [
"Year",
"Property Taxes",
"Tax Assessment"
],
"values": [
[
"2017",
",068",
"5,000"
],
[
"2016",
",864",
"2,000"
],
[
"2015",
",609",
"1,500"
]
]
},
这是我现在拥有的代码。我只是想 post 两行数据: 1 列 header 名称,以及 1 包含所有行数据(此时不必看起来很漂亮 - 我只是想完成映射)
@Serializable
@SerialName("Table")
@Parcelize
data class TableSection(
override val title: String? = null,
@SerialName("names")
val columnHeader: ArrayList<String?> = arrayListOf(),
@SerialName("values")
val tableData: ArrayList<TableRow> = arrayListOf(),
) : Section() {
@Composable
override fun Content(modifier: Modifier) {
return Column {
Row {
columnHeader.map {
Text(it ?: "")
}
}
Row {
tableData.map { row ->
row.tableRowValues.map { value ->
Text(value ?: "")
}
}
}
}
}
}
@Serializable
@Parcelize
data class TableRow(
@Serializable
val tableRowValues: ArrayList<String?> = arrayListOf(),
) : Parcelable
注意:标题和 Table 列 Headers 工作正常。引发错误的是 table 数据。
我最终创建了一个自定义序列化程序来获取嵌套值:
@Serializable(with = TableRowSerializer::class)
@Parcelize
data class TableRow(
val tableRowValues: List<String?> = arrayListOf(),
) : Parcelable
object TableRowSerializer : KSerializer<TableRow> {
private val serializer = ListSerializer(String.serializer())
override val descriptor: SerialDescriptor = serializer.descriptor
override fun serialize(encoder: Encoder, value: TableRow) {
val rowValues = value.tableRowValues
rowValues.let{rowValues as? List<String>}
?.let { encoder.encodeSerializableValue(serializer, it) }
}
override fun deserialize(decoder: Decoder): TableRow {
return TableRow(decoder.decodeSerializableValue(serializer))
}
}