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