Search code examples
androidfunctionkotlinif-statementonclicklistener

How can we set running order in setOnClickListener?


I have a favorite button, "check if favorite" function and checkRef variable. I am taking the values from Firebase for view pager adapter. I want to check these if i add this to my favorite or not.

This is my favorite button's setOnClickListener:

buttonLike.setOnClickListener()
            {
                checkFavorite() //
                if(firebaseAuth.currentUser == null)
                {
                    Toast.makeText(this@MainActivity,"pls login", Toast.LENGTH_SHORT).show()
                }
                else
                {
                    if (!checkRef)
                    {
                        removeFromFavorite()
                    }
                    else
                    {
                        addToFavorite()
                    }
                }
            }

And this is my checking function. This function changes the value of the checkRef.

private fun checkFavorite(){
        val checkId = binding.viewPager.currentItem.toString()
        val urlRef = userRef.child(firebaseAuth.uid!!).child("Favorites")
        urlRef.addListenerForSingleValueEvent(object :ValueEventListener{
            override fun onCancelled(error: DatabaseError) {
                print(error.message)
            }
            override fun onDataChange(snapshot: DataSnapshot) {
                if(snapshot.child(checkId).value == null)
                {
                    checkRef = true
                }
                else
                {
                    checkRef = false
                }
            }
        }
        )
    }

When I click the buttonLike button, it is not reading the checkFavorite function although at the top. It is continuing and checking the if-else blocks. After that, it reading checkFavorite function but I have to run checkFavorite() before if-else blocks because checkRef variable is checking in checkFavorite()

I added the Log's in if-else blocks and i saw that the function is doing if-else block before the top function.


Solution

  • the problem is that urlRef.addListenerForSingleValueEvent invoke a new thread, so the application continue his work exiting the function checkFavorite before to set the variable checkRef .

    you can solve in this way:

    you need a callback similar to something like:

    interface check_favorite_callback
    {
       void onEnd();
    }
    

    click listener:

    buttonLike.setOnClickListener()
            {
                checkFavorite(new check_favorite_callback(){
                   void onEnd(){
                      if(firebaseAuth.currentUser == null)
                {
                    Toast.makeText(this@MainActivity,"pls login", Toast.LENGTH_SHORT).show()
                }
                else
                {
                    if (!checkRef)
                    {
                        removeFromFavorite()
                    }
                    else
                    {
                        addToFavorite()
                    }
                }
                   }
                }) 
            }
    

    function checkFavorite:

    private fun checkFavorite(check_favorite_callback callback){
        val checkId = binding.viewPager.currentItem.toString()
        val urlRef = userRef.child(firebaseAuth.uid!!).child("Favorites")
        urlRef.addListenerForSingleValueEvent(object :ValueEventListener{
            override fun onCancelled(error: DatabaseError) {
                print(error.message)
                callback.onEnd();
            }
            override fun onDataChange(snapshot: DataSnapshot) {
                if(snapshot.child(checkId).value == null)
                {
                    checkRef = true
                }
                else
                {
                    checkRef = false
                }
                callback.onEnd();
            }
        }
        )
    }
    

    i write code directly in stackoverflow, so sintactically could be not perfect, try to understand the logic.