0
\$\begingroup\$

I am practicing Singleton pattern in kotlin.

It is a quiz app which has question tile with four options and one correctIndex.

McqOldActivity.classs

class McqOldActivity : AppCompatActivity() {

    var questions = mutableListOf<QuestionBO>()
    lateinit var mcqPagerAdapter: McqPagerAdapter

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

        val subjectName = "english"
        val levelNum = "0"
        val pathUrl = "rootNode/subRootNode/mcqRoot/$subjectName/$levelNum"
        val myRef = FirebaseDatabase.getInstance().getReference(pathUrl)

        mcqPagerAdapter = McqPagerAdapter(supportFragmentManager,questions)
        view_pager.adapter = mcqPagerAdapter

        val questionListener = object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                dataSnapshot.children.mapNotNullTo(questions) {
                    it.getValue<QuestionBO>(
                        QuestionBO::class.java
                    )
                }
                SingletonModel.updateQuestion(questions)
                mcqPagerAdapter.notifyDataSetChanged()
                view_pager.offscreenPageLimit = questions.size
            }

            override fun onCancelled(databaseError: DatabaseError) {
                println("loadPost:onCancelled ${databaseError.toException()}")
            }
        }

        myRef.addValueEventListener(questionListener)
    }
}

McqPagerAdapter.class

class McqPagerAdapter(fragmentManager: FragmentManager, private val questionList: List<QuestionBO>) : FragmentStatePagerAdapter(fragmentManager){

    override fun getItem(position: Int): Fragment {
        return McqFragment.newInstance(questionList.get(position),position,null)
    }

    override fun getCount(): Int {
        return questionList.size
    }
}

QuestionBO

@Parcelize
data class QuestionBO(
    val CorrectIndex: Int = -1, val Option1: String = "option 1", val Option2: String = "option 2",
    val Option3: String = "option 3", val Option4: String = "option 4",
    val Question: String = "Question"
) : Parcelable

SingletonModel.kt

class SingletonModel {

    companion object {
        ///val instance = SingletonModel()
        var questions = mutableListOf<QuestionBO>()
        var results = mutableListOf<ResultBO>()

        fun updateQuestion(questionsFromServer:MutableList<QuestionBO>){
            questions = questionsFromServer;
            results.clear()
            for(question in questions){
                results.add(ResultBO(question,false,null))
            }
        }

        fun updateSelectedAnswer(indexOfQuestion:Int,userSelectedIndex:Int){
            results.get(indexOfQuestion).isCorrectAnswer = questions.get(indexOfQuestion).CorrectIndex == userSelectedIndex
            results.get(indexOfQuestion).userSelectedOptionIndex = userSelectedIndex
        }

        fun getResult() : MutableList<ResultBO>{
            return results;
        }

        fun clearAll(){
            results.clear()
            questions.clear()
        }
    }
}

I call SingletonModel.updateQuestion(questions) when questions are fetched. and SingletonModel.clearAll() on Destory() .. Am I using Singleton in the right way?

Edit After attempting quiz I have to show result to user ..

val intent = Intent(this@McqOldActivity,ResultActivity::class.java)
            intent.putParcelableArrayListExtra("arrayListKey", ArrayList(SingletonModel.getResult()))
            startActivity(intent)
            SingletonModel.clearAll()

and get it like

var results:MutableList<ResultBO> =intent.getParcelableArrayListExtra<ResultBO>("arrayListKey") as MutableList<ResultBO>

Edit 2

McqFragment.class

class McqFragment: Fragment(),View.OnClickListener {
    var indexOfQuestion:Int? = -1
    var questionBO: QuestionBO? = null
    var onOptionSelectedListener:OnOptionSelectedListener? = null
    companion object {
        private const val KEY_QUESTION_BO = "questionKey"
        private const val KEY_POSITION = "positionKey"

        fun newInstance(questionBO: QuestionBO, position: Int,listener:OnOptionSelectedListener?) = McqFragment().apply {
            arguments = Bundle(2).apply {
                putParcelable(KEY_QUESTION_BO,questionBO)
                putInt(KEY_POSITION, position)
                onOptionSelectedListener = listener
            }
        }
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return LayoutInflater.from(container?.context).inflate(R.layout.mcq_fragment,container,false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        indexOfQuestion = arguments?.getInt(KEY_POSITION,-1)
        questionBO = arguments?.getParcelable<QuestionBO>(KEY_QUESTION_BO)
        questionTv.text = questionBO?.Question
        option1.text = questionBO?.Option1
        option2.text = questionBO?.Option2
        option3.text = questionBO?.Option3
        option4.text = questionBO?.Option4

        option1.setOnClickListener(this)
        option2.setOnClickListener(this)
        option3.setOnClickListener(this)
        option4.setOnClickListener(this)
    }

    override fun onClick(v: View?) {
        when(v?.id){
            R.id.option1 -> {
                SingletonModel.updateSelectedAnswer(indexOfQuestion!!,1);
                option1.background = resources.getDrawable(R.drawable.round_corner_view_filled,null)
                option2.background = resources.getDrawable(R.drawable.round_corner_view,null)
                option3.background = resources.getDrawable(R.drawable.round_corner_view,null)
                option4.background = resources.getDrawable(R.drawable.round_corner_view,null)
            }
            R.id.option2 -> {
                SingletonModel.updateSelectedAnswer(indexOfQuestion!!,2);
                option1.background = resources.getDrawable(R.drawable.round_corner_view,null)
                option2.background = resources.getDrawable(R.drawable.round_corner_view_filled,null)
                option3.background = resources.getDrawable(R.drawable.round_corner_view,null)
                option4.background = resources.getDrawable(R.drawable.round_corner_view,null)
            }
            R.id.option3 -> {
                SingletonModel.updateSelectedAnswer(indexOfQuestion!!,3);
                option1.background = resources.getDrawable(R.drawable.round_corner_view,null)
                option2.background = resources.getDrawable(R.drawable.round_corner_view,null)
                option3.background = resources.getDrawable(R.drawable.round_corner_view_filled,null)
                option4.background = resources.getDrawable(R.drawable.round_corner_view,null)
            }
            R.id.option4 -> {
                SingletonModel.updateSelectedAnswer(indexOfQuestion!!,4);
                option1.background = resources.getDrawable(R.drawable.round_corner_view,null)
                option2.background = resources.getDrawable(R.drawable.round_corner_view,null)
                option3.background = resources.getDrawable(R.drawable.round_corner_view,null)
                option4.background = resources.getDrawable(R.drawable.round_corner_view_filled,null)
            }
        }
    }
}

McqOldActivity fetch questions from firebase server.. McqPagerAdapter pass each question to McqFragment and when user select an option I update that answer using SingletonModel

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.