Android弹窗中Button的setOnClickListener方法失效问题求助
你的判断没错,问题确实出在提前inflate布局的操作上,具体原因和修复方案如下:
问题根源
你提前通过val dialogLayout = inflater.inflate(R.layout.dialog_create, null)创建了一个布局实例,并从中获取了createBtn和etDialog的引用。但在点击FloatingActionButton时,你调用了dialog.setContentView(R.layout.dialog_create)——这会让Dialog重新加载一个全新的dialog_create布局实例。
也就是说,你设置点击事件的createBtn,和弹窗里实际显示的按钮根本不是同一个对象,自然不会触发点击逻辑。
修复方案
有两种可行的修复方式,任选其一即可:
方式一:复用提前inflate的布局实例
保留你提前inflate的dialogLayout,在Dialog中直接使用这个实例,而不是重新加载布局:
actionBtn.setOnClickListener{ // 使用已经inflate好的dialogLayout,而非重新加载 dialog.setContentView(dialogLayout) dialog.show() }
方式二:在Dialog初始化后再获取控件引用(更推荐)
移除提前inflate布局和绑定控件的代码,改为在Dialog设置ContentView后,直接从Dialog中获取控件并设置点击事件,避免布局实例混乱:
class MainActivity : AppCompatActivity() { private lateinit var listView: ListView private lateinit var actionBtn: FloatingActionButton // 移除createBtn和etDialog的全局声明,改为局部获取 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) listView = findViewById(R.id.listView) actionBtn = findViewById(R.id.actionBtn) val list=ArrayList<HashMap<String,String>>() val from = arrayOf("todoItem") val to = intArrayOf(R.id.listItem) val dialog = Dialog(this) val simpleAdapter = SimpleAdapter(this, list, R.layout.list_item, from, to) listView.adapter = simpleAdapter actionBtn.setOnClickListener{ dialog.setContentView(R.layout.dialog_create) // 从Dialog当前的ContentView中获取控件 val createBtn = dialog.findViewById<Button>(R.id.createBtn) val etDialog = dialog.findViewById<EditText>(R.id.edTxtDialog) createBtn.setOnClickListener{ val todoItem = etDialog.text.toString() if(todoItem.isNotEmpty()){ val map = HashMap<String,String>() map["todoItem"] = todoItem list.add(map) simpleAdapter.notifyDataSetChanged() dialog.dismiss() } } dialog.show() } } }
额外提示
- 尽量避免提前创建与Dialog相关的布局实例,除非你确定会复用它
- 确保控件引用始终指向当前Dialog中实际显示的控件,否则会出现点击无响应、控件为空等问题
内容的提问来源于stack exchange,提问作者Rostyk
相关产品推荐
相关产品推荐

