Search code examples
kotlinandroid-recyclerviewandroid-viewpager2

Why does function called in Adapter from another activity always return false?


Inside ExamAcitivy :

passExamState always returns false even though its value changes to true after the setOnClickListener, when called in the adapter I need it to return the state acordingly. How do i propely pass the examState and its value to the adapter?

class ExamActivity : AppCompatActivity(){

    private var examState  = false

    private val questionData = QuestionData()
    private var  questionAdapter = QuestionAdapter(questionData)

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

        questionViewPager.adapter = questionAdapter
  

        endExam.setOnClickListener {
           examState=true
        }
            
    }

    fun passExamState() : Boolean {
        return examState
    }
}

Inside My ViewPager2Adapter :

class QuestionAdapter(private val questionData: QuestionData) :
RecyclerView.Adapter<QuestionAdapter.QuestionViewPagerViewHolder>() {

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

   //itemviews

    init {
        if (!ExamActivity().passExamState()) {
            getthis()
        }else{
            getthat()
        }
    }

}


override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QuestionViewPagerViewHolder {
    return QuestionViewPagerViewHolder(
        LayoutInflater.from(parent.context).inflate(R.layout.item_question, parent, false)
    )
}

override fun onBindViewHolder(holder: QuestionViewPagerViewHolder, position: Int) {

  

    //itemviews

    if (!ExamActivity().passExamState()){
        dothis()
    }else{
        dothat()

    }


}

//itemcount }


Solution

  • The problem is that you're creating a new ExamActivity instance and using that instance's property to check passExamState(). In this line, which appears twice in your code:

    if (!ExamActivity().passExamState()) {
    

    you are calling the ExamActivity constructor to construct a new Activity, so you are not checking the state of the actual Activity that is on the screen.

    The proper, encapsulated way to do this is to create the appropriate Boolean property in your Adapter, and allow your Activity to modify that property. This way of organizing the code reduces inter-dependence. The Adapter doesn't have to know about the existence of the Activity. For example:

    //In ExamActivity:
    
    endExam.setOnClickListener {
        examState = true // If you even need to track this property in the Activity.
                         // Maybe you can remove the property entirely.
    
        questionAdapter.examState = true
    }
    
    // Adapter class:
    
    class QuestionAdapter(private val questionData: QuestionData) :
    RecyclerView.Adapter<QuestionAdapter.QuestionViewPagerViewHolder>() {
       
        var examState = false
    
        inner class QuestionViewPagerViewHolder(itemView: View) : 
        RecyclerView.ViewHolder(itemView) {
    
            init {
                if (!examState) { // and the same in onBindViewHolder
                    getthis()
                }else{
                    getthat()
                }
           }
    
        }
    
        //...
    
    }