Тестовое приложение с фрагментами - PullRequest
0 голосов
/ 25 марта 2020

Я новичок в Android dev. Я делаю приложение с тестами controll.

Вот мой класс данных:

@Parcelize
class Test      (var id: Int,
                 var numberQuestion: String,
                 var question: String,
                 var questionImageSrc: String,
                 var examination: Boolean,
                 var typeQuestion: String,
                 var singleChoiceAnswers: ArrayList<singleChoiceAnswer>,
                 var multipleChoiceAnswers: ArrayList<multipleChoiceAnswers>,
                 var inputAnswer: ArrayList<inputAnswer>): Parcelable{

}

@Parcelize
class multipleChoiceAnswers(var letter: String,
                                 var text: String,
                                 var correctAnswer: Boolean,
                                 var checked: Boolean):Parcelable

@Parcelize
data class singleChoiceAnswer(var letter: String,
                              var text: String,
                              var correctAnswer: Boolean,
                              var checked: Boolean):Parcelable

@Parcelize
data class inputAnswer(var correctAnswer: String,
                        var userAnswer: String):Parcelable

Я беру данные из JSON вот так.

Затем я использую свой адаптер:

class TestAdapter(val test : ArrayList<Test>, private val testAdapterCallback: (Test, Int)-> Unit) : RecyclerView.Adapter<TestAdapter.ViewHolder>(){

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {

        val v = LayoutInflater.from(parent.context).inflate(R.layout.test_view_item, parent, false)


        return ViewHolder(v)
    }

    override fun getItemCount(): Int {
        return test.size
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val num : Test = test[position]
        holder.textView.text = num.id.toString()

        holder.cardView.setOnClickListener(){
            testAdapterCallback(num, position)
        }
    }

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){

        val cardView = itemView.findViewById<CardView>(R.id.testCardView)
        val textView = itemView.findViewById<TextView>(R.id.testTextView)

    }

}

В своей деятельности:

class TestActivity : AppCompatActivity() {

    private lateinit var urlToTest: String
    private val list = ArrayList<Test>()
    private var randomList = ArrayList<Test>()
    private var currentItem = 0
    private var fragmentsList = ArrayList<Fragment>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test)

        val title = getIntent().getStringExtra("TestTitle")
        setTitle(title)

        urlToTest = "http://sasmobile.ru" + getIntent().getStringExtra("urlToJson") + getIntent().getStringExtra("jsonName")


        val recView = findViewById<RecyclerView>(R.id.testRecyclerView)
        recView.layoutManager = LinearLayoutManager(this, RecyclerView.HORIZONTAL, false)

        val connector = Connector().isConnectedToNetwork(this)

        if (connector) {
            AsyncTaskHandler().execute(urlToTest)


            val submitButton : Button = findViewById<Button>(R.id.submitButton)
            submitButton.setOnClickListener{
                if (currentItem<9) {
                    testAdapterItemClick(randomList[currentItem + 1], currentItem)
                    currentItem += 1
                }
                if(currentItem==9){
                    submitButton.text="Finish Test"

                }
            }
        }
        else{
            submitButton.visibility=View.INVISIBLE
            openAlertDialog()
        }


    }


    private fun openAlertDialog(){
        val dialogBuilder = AlertDialog.Builder(this)
        val connector = Connector().isConnectedToNetwork(this)

        dialogBuilder.setMessage("Check your Internet connection")
            .setCancelable(false)

            .setPositiveButton("Try again", DialogInterface.OnClickListener{
                    dialog, id -> if (connector) {
                dialog.cancel()
                AsyncTaskHandler().execute(urlToTest)
            }
            else openAlertDialog()
            })


        val alertBox = dialogBuilder.create()
        alertBox.setTitle("Ooops")
        alertBox.show()
    }




    private fun testAdapterItemClick(item: Test, currI : Int) {

        val fT: FragmentTransaction = supportFragmentManager.beginTransaction()

        currentItem = currI

        if (item.typeQuestion == "input") {
            val bundle = Bundle()
            bundle.putParcelable("ITEM", item)

            if(!item.questionImageSrc.isNullOrEmpty())
                bundle.putString("IMAGE_KEY", item.questionImageSrc)

            fragmentsList[currentItem].setArguments(bundle)
            fT.add(R.id.frameLayout, fragmentsList[currentItem])
        }


        if (item.typeQuestion == "singleChoice") {
            val bundle = Bundle()
            bundle.putParcelable("ITEM", item)

            val count = item.singleChoiceAnswers.count()
            bundle.putInt("COUNT_KEY", count)

            fragmentsList[currentItem].setArguments(bundle)

            fT.add(R.id.frameLayout, fragmentsList[currentItem])
        }

        if (item.typeQuestion == "multipleChoice") {
            val bundle = Bundle()
            bundle.putString("NUMBER_KEY", item.numberQuestion)
            bundle.putString("QUESTION_KEY", item.question)

            val count = item.multipleChoiceAnswers.count()
            bundle.putInt("COUNT_KEY", count)


            for (i in 0 until count)
            {
                val curentSCA = item.multipleChoiceAnswers[i]

                bundle.putString("letterSCA$i", curentSCA.letter)
                bundle.putString("textSCA$i", curentSCA.text)

            }
            if(!item.questionImageSrc.isNullOrEmpty())
                bundle.putString("IMAGE_KEY", item.questionImageSrc)

            fragmentsList[currentItem].setArguments(bundle)

            fT.add(R.id.frameLayout, fragmentsList[currentItem])
        }

        fT.addToBackStack(null)
        fT.commit()

    }




    fun checkTest(exam: Boolean): Boolean{
       return exam
    }




    inner class AsyncTaskHandler() : AsyncTask<String, String, String>() {

        override fun onPreExecute() {
            val proggressBar: ProgressBar = findViewById(R.id.progressBarTest)
            proggressBar.visibility = View.VISIBLE
            super.onPreExecute()
        }


        override fun doInBackground(vararg params: String?): String {
            val res: String
            val connection = URL(urlToTest).openConnection() as HttpURLConnection

            try {
                connection.connect()
                res = connection.inputStream.use { it.reader().use { reader -> reader.readText() } }
            } finally {
                connection.disconnect()
            }
            return res
        }


        override fun onPostExecute(result: String?) {
            super.onPostExecute(result)
            if (progressBarTest.visibility == View.VISIBLE)
                progressBarTest.visibility = View.INVISIBLE
            jsonResult(result)
        }


        private fun jsonResult(jsonString: String?) {

            val jsonArray = JSONArray(jsonString)

            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")
                    val mlist = ArrayList<multipleChoiceAnswers>()
                    val ilist = ArrayList<inputAnswer>()
                    val slist = ArrayList<singleChoiceAnswer>()


                    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
                            )
                        )
                    }
                    list.add(
                        Test(
                            curentId,
                            curentNQ,
                            curentQ,
                            curentQIS,
                            curentEx,
                            typeQuestion,
                            slist,
                            mlist,
                            ilist
                        )
                    )

                }
                if (typeQuestion.contains("singleChoice")){
                    val mlist = ArrayList<multipleChoiceAnswers>()
                    val ilist = ArrayList<inputAnswer>()
                    val slist = ArrayList<singleChoiceAnswer>()
                    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
                            )
                        )
                    }

                    list.add(
                        Test(
                            curentId,
                            curentNQ,
                            curentQ,
                            curentQIS,
                            curentEx,
                            typeQuestion,
                            slist,
                            mlist,
                            ilist
                        )
                    )

                }
                if (typeQuestion.contains("input")){
                    val inputAnswer = jsonObject.getJSONArray("inputAnswer")
                    val mlist = ArrayList<multipleChoiceAnswers>()
                    val ilist = ArrayList<inputAnswer>()
                    val slist = ArrayList<singleChoiceAnswer>()

                    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
                        )
                    )
                }


            }

            randomList = SubmitTest().getRandomList(list)

            fragmentsList= SubmitTest().getFragmentList(randomList)
            println(fragmentsList.size.toString())


            val adapter =
                TestAdapter(randomList) { item, position ->
                    testAdapterItemClick(item, position)
                }

            testAdapterItemClick(randomList[currentItem], currentItem)

            val recView = findViewById<RecyclerView>(R.id.testRecyclerView)

            recView.adapter = adapter

        }

    }

}

Мне нужно сохранить состояние каждого фрагмента, а затем проверить правильные ответы. Но я могу посмотреть на каждый фрагмент только сразу. Вот что я вижу:

java.lang.IllegalStateException: Fragment already added: Fragment2{3dfc5f1 (11c50525-66ee-47ab-9b19-56f0d4022182) id=0x7f070064}

И как мне добавить фрагменты:

fun getFragmentList(listI: ArrayList<Test>): ArrayList<Fragment>{

        val listF = ArrayList<Fragment>()

        for (i in 0 until listI.size){
            val frag : Fragment

            if (listI[i].typeQuestion=="input"){
                frag= Fragment1()
                listF.add(frag)
            }
            else if (listI[i].typeQuestion=="singleChoice"){
                frag= Fragment2()
                listF.add(frag)
            }
            else if (listI[i].typeQuestion=="multipleChoice"){
                frag= Fragment3()
                listF.add(frag)
            }
        }

        return listF
    }

Что мне нужно изменить, если я хочу увидеть фрагмент более 1 раза. Пожалуйста, помогите мне) Я уже все перепробовал. Заранее спасибо)

PS Извините за мой Engli sh)

...