Vâng, bạn có thể tạo một bộ chuyển đổi kiểu tùy chỉnh để phân tích json theo layerType
như thế này:
class LayerAdapter {
@FromJson
fun fromJson(layerJson: LayerJson): Layer = when (layerJson.layerType) {
LayerType.SHAPE -> ShapeLayer(layerJson.layerType, layerJson.shape ?: "")
LayerType.TEXT -> TextLayer(layerJson.layerType, layerJson.text ?: "")
LayerType.IMAGE -> ImageLayer(layerJson.layerType, layerJson.image ?: "")
}
@ToJson
fun toJson(layer: Layer): LayerJson = when (layer) {
is ShapeLayer -> LayerJson(layer.type, shape = layer.shape)
is TextLayer -> LayerJson(layer.type, text = layer.text)
is ImageLayer -> LayerJson(layer.type, image = layer.image)
else -> throw RuntimeException("Not support data type")
}
}
Ở đây tôi có thực hiện một số thay đổi để lớp dữ liệu của bạn cho rõ ràng (một tài sản thêm cho mỗi Layer
loại, ví dụ như shape
cho ShapeLayer
):
sealed class Layer
data class ShapeLayer(val type: LayerType, val shape: String) : Layer()
data class TextLayer(val type: LayerType, val text: String) : Layer()
data class ImageLayer(val type: LayerType, val image: String) : Layer()
//LayerJson contains every possible property of all layers
data class LayerJson(val layerType: LayerType, val shape: String? = null, val text: String? = null, val image: String? = null) : Layer()
enum class LayerType {
SHAPE, TEXT, IMAGE
}
kiểm tra mã:
val moshi = Moshi.Builder()
.add(LayerAdapter())
.build()
val type = Types.newParameterizedType(List::class.java, Layer::class.java)
val adapter = moshi.adapter<List<Layer>>(type)
//Convert from json string to List<Layer>
val layers: List<Layer>? = adapter.fromJson("""
[
{"layerType":"SHAPE", "shape":"I am rectangle"},
{"layerType":"TEXT", "text":"I am text"},
{"layerType":"IMAGE", "image":"I am image"}
]
""".trimIndent())
layers?.forEach(::println)
//Convert a list back to json string
val jsonString: String = adapter.toJson(layers)
println(jsonString)
Output:
ShapeLayer(type=SHAPE, shape=I am rectangle)
TextLayer(type=TEXT, text=I am text)
ImageLayer(type=IMAGE, image=I am image)
[{"layerType":"SHAPE","shape":"I am rectangle"},{"layerType":"TEXT","text":"I am text"},{"image":"I am image","layerType":"IMAGE"}]
Edit: Bạn có thể thêm adapter như bình thường khi bạn đang cố gắng để phân tích đối tượng khác có chứa Layer
. Giả sử bạn có một đối tượng như thế này:
đang
data class LayerContainer(val layers: List<Layer>)
Thử nghiệm:
val moshi = Moshi.Builder()
.add(LayerAdapter())
.build()
val adapter = moshi.adapter(LayerContainer::class.java)
val layerContainer: LayerContainer? = adapter.fromJson("""
{
"layers": [
{"layerType":"SHAPE", "shape":"I am rectangle"},
{"layerType":"TEXT", "text":"I am text"},
{"layerType":"IMAGE", "image":"I am image"}
]
}
""".trimIndent())
layerContainer?.layers?.forEach(::println)
val jsonString: String = adapter.toJson(layerContainer)
println(jsonString)
Tôi nghĩ bạn đã bỏ lỡ phương pháp '@ ToJson'? Câu trả lời dưới đây là chính xác. –
Không có @ ToJson ở đó, tôi vừa bỏ qua tất cả các mã mà tôi nghĩ là không quan trọng ví dụ – miszmaniac
hm, sau đó, điều này trông giống như câu trả lời. bạn có làm cho nó hoạt động không? –