Search code examples
androidkotlinlisteneroncheckedchangedmaterialbutton

How do I get the listener from the MaterialButton.addOnCheckedChangeListener { "as a lambda" }


I have some MaterialButtons which changes checked state (in a toggle group scenario).

My plan is to listen to the Checked status through MaterialButtons addOnCheckedChangeListener

but I need to remove the listener when some conditions occure, how do I get the listener (object) from the lambda (and put it in the onCheckedChangeListener value) ?


   var onCheckedChangeListener: MaterialButton.OnCheckedChangeListener?=null
   
...


   myMaterialButton?.addOnCheckedChangeListener { button, isChecked ->
                    Log.i(TAG, "onViewCreated: button = $button, isChecked = $isChecked")
                    
                    if(button.isChecked)
                    {
                       //Use some variables which are reachable here 
                       //Do som work  
                    }
                    else
                    {
                        //Use some variables which are reachable here
                        //Do some other work
                    }

                }

...                

//Some condition prior to this causes me to remove the listener by using 
//removeOnCheckedChangeListener, but how do I get the onCheckedChangeListener from my 
//lambda above which I need to remove ?
                
    myMaterialButton?.removeOnCheckedChangeListener(onCheckedChangeListener)



The solution is certainly straightforward, but I cannot find any obvious answer.


Solution

  • If you are only ever using this single listener, it would be simpler to call myMaterialButton?.clearOnCheckedChangeListeners() so you don't have to keep track of the listener with a property.

    However, if you need to remove one of multiple listeners:

    You already have the property defined correctly. To create the listener object outside of the method you are passing it to, you prefix the lambda with the interface name. You can directly assign it to your property, and you can use the also scope function to also add this listener to your button.

    onCheckedChangeListener = MaterialButton.OnCheckedChangeListener { button, isChecked ->
        Log.i(TAG, "onViewCreated: button = $button, isChecked = $isChecked")
        if(button.isChecked)
        {
            //Use some variables which are reachable here 
            //Do som work  
        }
        else
        {
            //Use some variables which are reachable here
            //Do some other work
        }
    
    }.also { myMaterialButton?.addOnCheckedChangeListener(it) }
    

    Then to remove it:

    onCheckedChangeListener?.let {
        myMaterialButton?.removeOnCheckedChangeListener(it)
        onCheckedChangeListener = null
    }