嵌套数组和 JSON 的问题
Posted
技术标签:
【中文标题】嵌套数组和 JSON 的问题【英文标题】:Troubles with nested array and JSON 【发布时间】:2020-03-17 07:53:37 【问题描述】:您好)我是 android 开发新手。我的程序有问题。 这是我的模型:
data class Test (val id: Int,
val numberQuestion: String,
val question: String,
val questionImageSrc: String,
val examination: Boolean,
val typeQuestion: String,
val singleChoiceAnswers: ArrayList<singleChoiceAnswer>,
val multipleChoiceAnswers: ArrayList<multipleChoiceAnswers>,
val inputAnswer: ArrayList<inputAnswer>)
data class multipleChoiceAnswers(val letter: String,
val text: String,
val correctAnswer: Boolean,
val checked: Boolean)
data class singleChoiceAnswer(val letter: String,
val text: String,
val correctAnswer: Boolean,
val checked: Boolean)
data class inputAnswer(val correctAnswer: String,
val userAnswer: String)
这就是我从 JSON 中获取数据的方式:
private fun jsonResult(jsonString: String?)
val jsonArray = JSONArray(jsonString)
val list = ArrayList<Test>()
val slist = ArrayList<singleChoiceAnswer>()
val mlist = ArrayList<multipleChoiceAnswers>()
val ilist = ArrayList<inputAnswer>()
for (i in 0 until jsonArray.length())
val jsonObject = jsonArray.getJSONObject(i)
val typeQuestion = jsonObject.getString("typeQuestion")
val curentId = jsonObject.optInt("id")
val curentNQ = jsonObject.optString("numberQuestion")
val curentQ = jsonObject.optString("question")
val curentQIS = jsonObject.optString("questionImageSrc")
val curentEx = jsonObject.optBoolean("examination")
if (typeQuestion.contains("multipleChoice"))
val multipleChoiceAnswers = jsonObject.getJSONArray("multipleChoiceAnswers")
for (sc in 0 until multipleChoiceAnswers.length())
val curentMCA = multipleChoiceAnswers.getJSONObject(sc)
val letter = curentMCA.optString("letter")
val text = curentMCA.optString("text")
val correctAnswer = curentMCA.optBoolean("correctAnswer")
val checked = curentMCA.optBoolean("checked")
mlist.add(multipleChoiceAnswers(letter, text, correctAnswer, checked))
if (typeQuestion.contains("singleChoice"))
val singleChoiceAnswer = jsonObject.getJSONArray("singleChoiceAnswers")
for (sc in 0 until singleChoiceAnswer.length())
val curentSCA = singleChoiceAnswer.getJSONObject(sc)
val letter = curentSCA.optString("letter")
val text = curentSCA.optString("text")
val correctAnswer = curentSCA.optBoolean("correctAnswer")
val checked = curentSCA.optBoolean("checked")
slist.add(singleChoiceAnswer(letter, text, correctAnswer, checked))
if (typeQuestion.contains("input"))
val inputAnswer = jsonObject.getJSONArray("inputAnswer")
for (sc in 0 until inputAnswer.length())
val curentIA = inputAnswer.getJSONObject(sc)
val correctAnswer = curentIA.optString("correctAnswer")
val userAnswer = curentIA.optString("userAnswer")
ilist.add(inputAnswer(correctAnswer,userAnswer))
list.add(Test(curentId, curentNQ, curentQ, curentQIS, curentEx, typeQuestion, slist, mlist, ilist))
val adapter = TestAdapter(list) item ->
testAdapterItemClick(item)
val recView = findViewById<RecyclerView>(R.id.testRecyclerView)
recView.adapter = adapter
这是我的JSON 的链接。如果需要)
然后我正在做类似的事情:
private fun testAdapterItemClick(item: Test)
val fT: FragmentTransaction = supportFragmentManager.beginTransaction()
val frag1: Fragment1 = Fragment1()
val frag2: Fragment2 = Fragment2()
if (item.typeQuestion == "input")
val bundle = Bundle()
bundle.putString("NUMBER_KEY", item.numberQuestion)
bundle.putString("QUESTION_KEY", item.question)
if(!item.questionImageSrc.isNullOrEmpty())
bundle.putString("IMAGE_KEY", item.questionImageSrc)
frag1.setArguments(bundle)
fT.add(R.id.frameLayout, frag1)
if (item.typeQuestion == "singleChoice")
val bundle = Bundle()
bundle.putString("NUMBER_KEY", item.numberQuestion)
bundle.putString("QUESTION_KEY", item.question)
val count = item.singleChoiceAnswers.size
Toast.makeText(this, count.toString(), Toast.LENGTH_LONG).show()
// bundle.putInt("COUNT_KEY", count)
for (i in 0 until count)
val curentSCA = item.singleChoiceAnswers[i]
bundle.putString("letterSCA$i", curentSCA.letter)
bundle.putString("textSCA$i", curentSCA.text)
frag2.setArguments(bundle)
fT.add(R.id.frameLayout, frag2)
我需要获取确定项目的 ArrayList 并使用 bundle 将其数据放入片段中。 但是我在片段中有一个问题:
public override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View?
val rootView = inflater.inflate(R.layout.fragment2, container, false)
val questionNumber = rootView.findViewById(R.id.questionNumber) as TextView
val questionText = rootView.findViewById(R.id.Question) as TextView
val questionImage = rootView.findViewById(R.id.questionImage) as ImageView
val qN : String = getArguments()?.getString("NUMBER_KEY").toString()
val quest: String = getArguments()?.getString("QUESTION_KEY").toString()
val qI: String = getArguments()?.getString("IMAGE_KEY").toString()
questionNumber.text=qN
questionText.text=quest
Picasso.get().load(qI).into(questionImage)
val radioGroup = rootView.findViewById(R.id.radioGroupSetectTest) as RadioGroup
val count : Int = getArguments()!!.getInt("COUNT_KEY")
val context = getContext()
for (i in 0 until count)
val curentRB = RadioButton(context)
val curLetter = getArguments()?.getString("letterSCA$i")
val curText = getArguments()?.getString("textSCA$i")
curentRB.setText(curLetter+" "+curText)
radioGroup.addView(curentRB)
它从像 screen 这样的所有项目中放入了 singleChoiseAnswer 的所有值。请帮帮我)我知道这是一个简单的问题,但我真的不明白)
提前致谢) 附言S对不起我的英语)
【问题讨论】:
你能说出片段中的问题吗? @theanilpaudel 很可能问题出在我将值放入片段的循环中。我只需要放一个数组singleChoiceAnswer,但它把所有来自JSON的sinleCHoceArray,看屏幕 【参考方案1】:首先,你需要将你的Json转换成Kotlin类,你可以使用GSON 将您的 json 转换为像这样的 kotlin 数据类
import android.os.Parcel
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
data class QuestionResponse(
@field:SerializedName("multipleChoiceAnswers")
val multipleChoiceAnswers: List<MultipleChoiceAnswersItem?>? = null,
@field:SerializedName("inputAnswer")
val inputAnswer: List<InputAnswer?>? = null,
@field:SerializedName("numberQuestion")
val numberQuestion: String? = null,
@field:SerializedName("question")
val question: String? = null,
@field:SerializedName("typeQuestion")
val typeQuestion: String? = null,
@field:SerializedName("examination")
val examination: Boolean? = null,
@field:SerializedName("id")
val id: Int? = null,
@field:SerializedName("singleChoiceAnswers")
val singleChoiceAnswers: List<MultipleChoiceAnswersItem?>? = null,
@field:SerializedName("questionImageSrc")
val questionImageSrc: String? = null
) : Parcelable
constructor(parcel: Parcel) : this(
parcel.createTypedArrayList(MultipleChoiceAnswersItem),
parcel.createTypedArrayList(InputAnswer),
parcel.readString(),
parcel.readString(),
parcel.readString(),
parcel.readValue(Boolean::class.java.classLoader) as? Boolean,
parcel.readValue(Int::class.java.classLoader) as? Int,
parcel.createTypedArrayList(MultipleChoiceAnswersItem),
parcel.readString()
)
override fun writeToParcel(parcel: Parcel, flags: Int)
parcel.writeTypedList(multipleChoiceAnswers)
parcel.writeTypedList(inputAnswer)
parcel.writeString(numberQuestion)
parcel.writeString(question)
parcel.writeString(typeQuestion)
parcel.writeValue(examination)
parcel.writeValue(id)
parcel.writeTypedList(singleChoiceAnswers)
parcel.writeString(questionImageSrc)
override fun describeContents(): Int
return 0
companion object CREATOR : Parcelable.Creator<QuestionResponse>
override fun createFromParcel(parcel: Parcel): QuestionResponse
return QuestionResponse(parcel)
override fun newArray(size: Int): Array<QuestionResponse?>
return arrayOfNulls(size)
import android.os.Parcel
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
data class MultipleChoiceAnswersItem(
@field:SerializedName("letter")
val letter: String? = null,
@field:SerializedName("checked")
val checked: Boolean? = null,
@field:SerializedName("text")
val text: String? = null,
@field:SerializedName("correctAnswer")
val correctAnswer: Boolean? = null
) : Parcelable
constructor(parcel: Parcel) : this(
parcel.readString(),
parcel.readValue(Boolean::class.java.classLoader) as? Boolean,
parcel.readString(),
parcel.readValue(Boolean::class.java.classLoader) as? Boolean
)
override fun writeToParcel(parcel: Parcel, flags: Int)
parcel.writeString(letter)
parcel.writeValue(checked)
parcel.writeString(text)
parcel.writeValue(correctAnswer)
override fun describeContents(): Int
return 0
companion object CREATOR : Parcelable.Creator<MultipleChoiceAnswersItem>
override fun createFromParcel(parcel: Parcel): MultipleChoiceAnswersItem
return MultipleChoiceAnswersItem(parcel)
override fun newArray(size: Int): Array<MultipleChoiceAnswersItem?>
return arrayOfNulls(size)
import android.os.Parcel
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
data class InputAnswer(
@field:SerializedName("correctAnswer")
val correctAnswer: String? = null,
@field:SerializedName("userAnswer")
val userAnswer: String? = null) : Parcelable
constructor(parcel: Parcel) : this(
parcel.readString(),
parcel.readString()
)
override fun writeToParcel(parcel: Parcel, flags: Int)
parcel.writeString(correctAnswer)
parcel.writeString(userAnswer)
override fun describeContents(): Int
return 0
companion object CREATOR : Parcelable.Creator<InputAnswer>
override fun createFromParcel(parcel: Parcel): InputAnswer
return InputAnswer(parcel)
override fun newArray(size: Int): Array<InputAnswer?>
return arrayOfNulls(size)
要了解 Parcelable,请访问 link
然后当这完成后,像这样解析JSON
private fun jsonResult(jsonString: String?)
val jsonArray = JSONArray(jsonString)
val list = ArrayList<QuestionResponse>()
val slist = ArrayList<MultipleChoiceAnswersItem>()
val mlist = ArrayList<MultipleChoiceAnswersItem>()
val ilist = ArrayList<InputAnswer>()
for (i in 0 until jsonArray.length())
val jsonObject = jsonArray.getJSONObject(i)
val typeQuestion = jsonObject.getString("typeQuestion")
val curentId = jsonObject.optInt("id")
val curentNQ = jsonObject.optString("numberQuestion")
val curentQ = jsonObject.optString("question")
val curentQIS = jsonObject.optString("questionImageSrc")
val curentEx = jsonObject.optBoolean("examination")
if (typeQuestion.contains("multipleChoice"))
val multipleChoiceAnswers = jsonObject.getJSONArray("multipleChoiceAnswers")
for (sc in 0 until multipleChoiceAnswers.length())
val curentMCA = multipleChoiceAnswers.getJSONObject(sc)
val letter = curentMCA.optString("letter")
val text = curentMCA.optString("text")
val correctAnswer = curentMCA.optBoolean("correctAnswer")
val checked = curentMCA.optBoolean("checked")
mlist.add(MultipleChoiceAnswersItem(letter,checked, text, correctAnswer))
if (typeQuestion.contains("singleChoice"))
val singleChoiceAnswer = jsonObject.getJSONArray("singleChoiceAnswers")
for (sc in 0 until singleChoiceAnswer.length())
val curentSCA = singleChoiceAnswer.getJSONObject(sc)
val letter = curentSCA.optString("letter")
val text = curentSCA.optString("text")
val correctAnswer = curentSCA.optBoolean("correctAnswer")
val checked = curentSCA.optBoolean("checked")
slist.add(MultipleChoiceAnswersItem(letter, checked,text, correctAnswer))
if (typeQuestion.contains("input"))
val inputAnswer = jsonObject.getJSONArray("inputAnswer")
for (sc in 0 until inputAnswer.length())
val curentIA = inputAnswer.getJSONObject(sc)
val correctAnswer = curentIA.optString("correctAnswer")
val userAnswer = curentIA.optString("userAnswer")
ilist.add(InputAnswer(correctAnswer,userAnswer))
val questionResponse = QuestionResponse(mlist,ilist,curentNQ,curentQ,typeQuestion,curentEx,curentId,slist,curentQIS)
//pass this questionResponse to your adapter
然后在适配器项目中点击
private fun testAdapterItemClick(item: Test)
val fT: FragmentTransaction = supportFragmentManager.beginTransaction()
val frag1: Fragment1 = Fragment1()
val frag2: Fragment2 = Fragment2()
if (item.typeQuestion == "input")
val bundle = Bundle()
bundle.putParcelable("input", item)
frag1.setArguments(bundle)
fT.add(R.id.frameLayout, frag1)
// do the same for the rest
然后在片段中
public override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View?
val rootView = inflater.inflate(R.layout.fragment2, container, false)
val questionNumber = rootView.findViewById(R.id.questionNumber) as TextView
val questionText = rootView.findViewById(R.id.Question) as TextView
val questionImage = rootView.findViewById(R.id.questionImage) as ImageView
val item = arguments.getParcelable("input")
// val arraylist = arguments.getParcelableArrayList<YOUR_CLASS_TYPE>("key") //for arrays you can do it like this
//then set it in the radiobutton like this item.getCurrentText and so on
【讨论】:
以上是关于嵌套数组和 JSON 的问题的主要内容,如果未能解决你的问题,请参考以下文章