What I want to achieve:
I want to get the button text as parameter for the function
What I want:
// Operators - setOnClickListener
btnDivide.setOnClickListener { viewModel.mountOperator(it.text) }
btnMultiply.setOnClickListener { viewModel.mountOperator(it.text) }
btnMinus.setOnClickListener { viewModel.mountOperator(it.text) }
btnPlus.setOnClickListener { viewModel.mountOperator(it.text) }
What is working:
// Operators - setOnClickListener
btnDivide.setOnClickListener { viewModel.mountOperator(btnDivide.text) }
btnMultiply.setOnClickListener { viewModel.mountOperator(btnMultiply.text) }
btnMinus.setOnClickListener { viewModel.mountOperator(btnMinus.text) }
btnPlus.setOnClickListener { viewModel.mountOperator(btnPlus.text) }
The problem that is appearing:
Error: Unresolved reference: text
, when i am doing it.text
But inside setOnClickListener{ it: View!
}, I saw this preview as it is generally shown. So I thought that, here it
is refering to the button to which I am setting the onClickListener
.
if there is any confusion about the question, please write in the comment. If my approach is wrong, share in the comments
CodePudding user response:
So I thought that, here it is referring to the button to which I am setting the onClickListener.
Here, it
is of type View
and not of type Button
, or whatever type of specific view type you want it to be, so because not all views have a text
property (which means that View
doesn't have something called text
, but Button
might), you can use something like this:
btnDivide.setOnClickListener { viewModel.mountOperator((it as Button).text) }
where you can replace Button
with whatever type of view it is.
it as Button
is casting the View
we get into our specific type, in your case I'm assuming this will be a button, but you can cast it to whatever type of view it actually is.
it: View!
here does refer to the button you're setting the onClickListener to, but it's returned to you as a View
and not of a more specific type
CodePudding user response:
Also to follow up on @a_local_nobody's answer, the reason it's just passing in a generic View
and not the type you're setting the click listener on, is because you can create a single listener object/function and reuse it for all the things that need to handle clicks (which could be different subclasses of View
)
So if you like, you could make one of those and use it instead of repeating the code for each button:
fun handleButtonClick(view: View) {
if (view is Button) viewModel.mountOperator(view.text)
}
btnDivide.setOnClickListener { handleButtonClick(it) }
// or as a function reference
btnMultiply.setOnClickListener(::handleButtonClick)
And another thing you can do when you're assigning multiple identical click listeners (or doing the same anything to a bunch of things) is to just do a loop
listOf(btnDivide, btnMultiply, btnMinus, btnPlus).forEach {
it.setOnClickListener { //bla bla }
}
that works for reusing a function reference or just creating a new one for each listener (like you're doing in your question) - it just saves you repeating yourself, it can be easier to read, and if you need to make changes you only have to do it in one place