ListView条目点击时弹出PopupMenu的实现问题
看起来你把两个功能结合的时候踩了几个关键的坑,我帮你梳理下代码里的问题,然后给出修正后的版本:
你的代码里的核心错误点
- 上下文参数错误:在匿名的
OnItemClickListener里使用this,这里的this指向的是OnItemClickListener实例,而不是你的Activity,PopupMenu需要的是Activity级别的上下文,必须明确指定外部类的上下文。 - 无效的锚点View:你写的
val listPopupmenu = View(tl+[position])完全不符合View的构造逻辑,View需要传入Context才能创建,而且这里你应该用被点击的列表项View作为PopupMenu的锚点(也就是onItemClick参数里的view)。 - 多余的触发逻辑:你不需要额外创建View再设置点击事件来弹出菜单,直接在
onItemClick方法里调用弹出即可。 - Toast内容错误:
${textView}会输出TextView的对象信息,你应该显示被点击的列表项文本或者选中的菜单选项文本。 - MenuItem点击事件返回值错误:应该返回
true表示你已经处理了这个菜单点击事件,否则系统可能会继续传递事件导致异常。
修正后的完整代码
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.test) val textView = findViewById<TextView>(R.id.textView) val tl = arrayOf("a","a","a","a","a") val listview = findViewById<ListView>(R.id.tlist) val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, tl) listview.adapter = adapter listview.onItemClickListener = object : AdapterView.OnItemClickListener{ override fun onItemClick( parent: AdapterView<*>?, view: View?, position: Int, id: Long ) { // 正确传入Activity上下文,并用被点击的列表项作为菜单锚点 val showPopUp = PopupMenu(this@TestActivity, view!!) // 菜单选项点击处理,返回true表示事件已处理 showPopUp.setOnMenuItemClickListener { menuItem -> val selectedText = when(menuItem.itemId) { 0 -> "Item 0 被选中" 1 -> "Item 1 被选中" 2 -> "Item 2 被选中" 3 -> "Item 3 被选中" else -> "" } textView.text = selectedText // 底部弹出选中提示 Toast.makeText(applicationContext, selectedText, Toast.LENGTH_SHORT).show() true } // 添加菜单选项 showPopUp.menu.add(Menu.NONE, 0, 0, "Item 0") showPopUp.menu.add(Menu.NONE, 1, 1, "Item 1") showPopUp.menu.add(Menu.NONE, 2, 2, "Item 2") showPopUp.menu.add(Menu.NONE, 3, 3, "Item 3") // 直接在条目点击时弹出菜单 showPopUp.show() // 可选:显示列表条目被点击的提示 Toast.makeText(applicationContext, "列表项 ${tl[position]} 被点击", Toast.LENGTH_SHORT).show() } } }
修改后的效果
点击ListView的任意条目,菜单会在该条目位置弹出;选择菜单选项后,底部会弹出Toast提示你选中了哪个选项,同时textView也会同步更新对应的文本。
内容的提问来源于stack exchange,提问作者Joshu
相关产品推荐
相关产品推荐

