简体   繁体   中英

Android/Kotlin onClick from a Fragment

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM