Kotlin自定义AlertDialog内置Spinner无法获取选中项报错问题问询
问题核心原因
- 你创建了两个完全独立的
fragment_popup布局实例:- 第一个是MainActivity点击事件中LayoutInflater inflate的实例,你仅给这个实例的Spinner设置了选中监听,但这个View从未被添加到Dialog中
- 第二个是CustomAlert的
showDialog2方法中调用setContentView(R.layout.fragment_popup)时重新inflate的全新实例,这个实例的Spinner没有设置任何监听,自然无法触发选中回调
- 代码存在冗余逻辑错误:在
onItemSelected回调中重复调用setSelection,会触发循环回调,导致输入事件处理混乱 - LayoutInflater使用ApplicationContext作为context,可能引发布局主题适配问题
修复代码
1. 修改CustomAlert类,接收外部传入的初始化完成的布局
class CustomAlert { fun showDialog2(activity: Activity?, contentView: View) { val dialog = Dialog(activity!!) dialog.requestWindowFeature(Window.FEATURE_NO_TITLE) dialog.setCancelable(false) // 直接使用外部传入的已初始化布局,不再重复inflate dialog.setContentView(contentView) val dialogButton: Button = dialog.findViewById(R.id.button3) dialogButton.setOnClickListener { dialog.dismiss() } dialog.show() } }
2. 修改MainActivity点击事件逻辑
button.setOnClickListener { // 使用Activity作为LayoutInflater的context,不要用ApplicationContext val view = LayoutInflater.from(this).inflate( R.layout.fragment_popup, null ) view.spinner01.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onItemSelected( parent: AdapterView<*>?, view: View?, position: Int, id: Long ) { Toast.makeText( this@MainActivity, resources.getStringArray(R.array.planet)[position], Toast.LENGTH_SHORT ).show() // 删掉冗余的setSelection调用,避免循环触发回调 } override fun onNothingSelected(parent: AdapterView<*>?) { } } val alert = CustomAlert() // 将已设置监听的布局传入Dialog alert.showDialog2(this, view) }
InputEventReceiver报错说明
该报错是因为原代码在onItemSelected中重复调用setSelection触发了循环回调,同时未附加到窗口的View实例被回收后,系统仍尝试处理对应输入事件导致。上述修改后问题会自动解决。
内容的提问来源于stack exchange,提问作者IsLearning
相关产品推荐
相关产品推荐

