I am working on an app with a Tab layout where the user interfaces with various functions from different fragments. Getting button onClick
listeners to work is causing me problems and some confusion. I have a fragment that has some number inputs as EditText
s and buttons that activate methods (in theory). A simple one I want to implement is a rest button that simply resets the value in the number input to 1
. I thought this override of onClick()
would have worked in the Fragment's .kt
file:
class RatioFragment : Fragment(), View.OnClickListener {
private var param1: String? = null
private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_ratio, container, false)
val offsetResetButton: Button = view.findViewById(R.id.offsetResetButton)
offsetResetButton.setOnClickListener(this)
return view
}
companion object {
@JvmStatic
fun newInstance(param1: String, param2: String) =
RatioFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
override fun onClick(view: View?) {
when (view?.id) {
R.id.offsetResetButton -> {
hideKeyboard()
offsetNum = 1
offsetDen = 1
view.findViewById<EditText>(R.id.offsetNum).setText("1")
view.findViewById<EditText>(R.id.offsetDen).setText("1")
}
}
}
}
but the app crashes when I click the offsetResetButton
button. The var
s offsetNum
and offsetDen
are from elsewhere in the project, but it seems that trying to access my two text edits and setting new text causes issues. In particular I get the error
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.EditText.setText(java.lang.CharSequence)' on a null object reference
Wonder what's wrong here or if there is a better way to accomplish this.
I think you are getting tripped up by variable shadowing. Normally, in a Fragment
with Kotlin, view
would refer to whatever View you returned from onCreateView()
, which likely includes the EditText
s you're looking for. However, your implementation of onClick()
names its parameter view
, so view.findViewById()
will only scan the hierarchy of the view that was clicked.
override fun onClick(view: View?) { //... // these only search within the parameter view, ie a Button view.findViewById<EditText>(R.id.offsetNum).setText("1") view.findViewById<EditText>(R.id.offsetDen).setText("1") }
Change your onClick()
signature to use a different parameter name:
override fun onClick(v: View?) {
// ...
// these now search the entire fragment hierarchy
view.findViewById<EditText>(R.id.offsetNum).setText("1")
view.findViewById<EditText>(R.id.offsetDen).setText("1")
}
Unrelated, but I recommend not implementing View.OnClickListener
in your fragments/activities. Rather, just use a lambda when you set the click listener:
val offsetResetButton: Button = view.findViewById(R.id.offsetResetButton)
offsetResetButton.setOnClickListener { onOffsetResetClick() }
private fun onOffsetResetClick() {
// your code here
}
When you do it this way, you don't have to worry about when(view.id)
or anything like that, because you know the method can only be called by clicks on one particular button.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.