Kotlin中Fragment旋转屏幕时Spinner触发非空参数为空错误的解决方法
解决屏幕旋转时Fragment崩溃的非空参数问题
你遇到的崩溃核心原因是控件引用为null,但被传递给了要求非空的Kotlin方法,触发了Intrinsics.checkParameterIsNotNull的参数检查错误。具体问题和修复方案如下:
问题根源
- Spinner初始化完全错误:你直接写了
val spinner = lol,这根本没有正确获取布局中id为lol的Spinner控件。屏幕旋转后Fragment会重建,此时这个spinner变量是null,调用spinner.adapter时就会把null传给非空参数的方法,直接引发崩溃。 - 其他控件未正确绑定:
editText、editText2、button这些控件你直接使用了id名,但如果没有启用kotlin-android-extensions插件或者使用ViewBinding,这些变量并不会自动关联到布局中的控件,旋转后同样会变成null,导致后续操作出错。
修复方案
我们需要通过findViewById正确获取所有控件的引用,并且在onViewCreated中完成绑定(因为此时View已经创建完成)。修改后的Fragment代码如下:
private var mListener: OnFragmentInteractionListener? = null override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater!!.inflate(R.layout.fragment_first, container, false) } override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 确保view非空,避免后续空指针 view ?: return // 正确获取所有控件引用 val spinner = view.findViewById<Spinner>(R.id.lol) val editText = view.findViewById<EditText>(R.id.editText) val editText2 = view.findViewById<EditText>(R.id.editText2) val button = view.findViewById<Button>(R.id.button) val textView = view.findViewById<TextView>(R.id.textView) // 设置Spinner适配器 spinner.adapter = ArrayAdapter( requireContext(), R.layout.support_simple_spinner_dropdown_item, resources.getStringArray(R.array.atoms) ) as SpinnerAdapter // Spinner选择监听 spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) { val atomicWeight = when (spinner.selectedItem.toString()) { "H" -> "1" "He" -> "4" "C" -> "12" "O" -> "16" else -> "" } editText.setText(atomicWeight) } override fun onNothingSelected(parent: AdapterView<*>) { // 可选:设置默认提示 editText.setText("") } } // 计算按钮点击监听 button.setOnClickListener { val weightStr = editText2.text.toString().trim() val atomicWeightStr = editText.text.toString().trim() if (weightStr.isNotEmpty() && atomicWeightStr.isNotEmpty()) { try { val weight = weightStr.toDouble() val atomicWeight = atomicWeightStr.toDouble() val moles = weight / atomicWeight textView.text = String.format("%.2f moles", moles) // 格式化结果更友好 } catch (e: NumberFormatException) { textView.text = "请输入有效的数字" } } else { textView.text = "请填写完整数值" } } }
额外优化建议
- 推荐使用ViewBinding替代
findViewById,它更安全且代码更简洁,能彻底避免空指针问题。 - 如果只是想临时禁止屏幕旋转,可以取消注释
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT),但这只是规避问题,还是建议修复控件绑定的根本问题。 - 添加
NumberFormatException捕获,防止用户输入非数字内容导致额外崩溃。
内容的提问来源于stack exchange,提问作者a2krocks
相关产品推荐
相关产品推荐

