Android中遍历指定JSON对象并生成单个列表的技术实现
Alright, let's break down how to take that nested JSON structure and collect all the entries from the sum arrays into a single list in Android. I'll walk you through two practical approaches—using Android's built-in JSONObject and using Gson for a more streamlined solution.
Using Android's Native JSONObject (No External Dependencies)
First, let's define a simple data class to hold each entry from the sum array. This makes it easier to work with the data later:
data class TransactionEntry( val name: String, val budgetValue: Int, val actualValue: Int, val catID: Int, val iconName: String?, val iconColor: String?, val budgetHeadId: Int )
Next, here's the code to parse the JSON and build your single list:
fun parseJsonToSingleList(jsonString: String): List<TransactionEntry> { val combinedList = mutableListOf<TransactionEntry>() try { // Parse the root JSON object val rootObject = JSONObject(jsonString) // Get all top-level keys (like "My Income", "My Growth") val topLevelKeys = rootObject.keys() while (topLevelKeys.hasNext()) { val sectionKey = topLevelKeys.next() // Get the object for each top-level section val sectionObject = rootObject.getJSONObject(sectionKey) // Extract the "sum" array from the section val sumArray = sectionObject.getJSONArray("sum") // Iterate through each item in the sum array for (i in 0 until sumArray.length()) { val entryObject = sumArray.getJSONObject(i) // Map the JSON object to our data class val entry = TransactionEntry( name = entryObject.getString("name"), budgetValue = entryObject.getInt("budgetvalue"), actualValue = entryObject.getInt("actualvalue"), catID = entryObject.getInt("catID"), // Use optString to safely handle null values without exceptions iconName = entryObject.optString("iconname"), iconColor = entryObject.optString("iconcolor"), budgetHeadId = entryObject.getInt("budgetHeadId") ) combinedList.add(entry) } } } catch (e: JSONException) { // Handle parsing errors (log, show error message, etc.) e.printStackTrace() } return combinedList }
Using Gson (Simpler, Less Boilerplate)
If you're okay with adding a dependency, Gson makes this parsing much cleaner. First, add the Gson dependency to your app-level build.gradle (or build.gradle.kts):
implementation 'com.google.code.gson:gson:2.10.1' // Use the latest stable version
Then define your data classes—note the @SerializedName annotation to map JSON keys to your variable names:
data class SectionData( val catResponse: Any?, val sum: List<TransactionEntry>, val spendAmount: Int, val incomeAmount: Any? ) data class TransactionEntry( val name: String, @SerializedName("budgetvalue") val budgetValue: Int, @SerializedName("actualvalue") val actualValue: Int, val catID: Int, val iconname: String?, val iconcolor: String?, val budgetHeadId: Int )
Now the parsing code becomes far more concise:
fun parseWithGson(jsonString: String): List<TransactionEntry> { val gson = Gson() // Parse the JSON into a map where keys are the top-level section names val sectionMap = gson.fromJson( jsonString, object : TypeToken<Map<String, SectionData>>() {}.type ) // Combine all sum lists into one return sectionMap.values.flatMap { it.sum } }
Notes to Keep in Mind
- Null Handling: The native approach uses
optStringto avoidJSONExceptionwhen fields likeiconnameare null. With Gson, nullable types (String?) handle this automatically. - Error Handling: Always wrap parsing code in a try-catch block (for native) or handle potential parsing failures gracefully—invalid JSON can crash your app if unhandled.
- Scalability: If your JSON might have more top-level sections later, both approaches will handle them automatically without changing code.
内容的提问来源于stack exchange,提问作者user2841552

