Проблемы с вложенным массивом и JSON - PullRequest
0 голосов
/ 17 марта 2020

Привет) Я новичок в Android dev. И у меня проблема с моей программой. Это моя модель:

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)

        }

Он помещает все значения singleChoiseAnswer из всех элементов, подобных этому screen . Пожалуйста, помогите мне) Я знаю, что это простая проблема, но я действительно не понимаю)

Заранее спасибо) PS Извините за мой Engli sh)

1 Ответ

0 голосов
/ 17 марта 2020

Прежде всего, вам необходимо преобразовать 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 go для этой ссылки

Затем, когда это будет завершено, выполните синтаксический анализ 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


    }




}

Затем в Адаптер Item click

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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...