如何使用单个触摸监听器处理多个视图的点击事件以优化重复代码
如何使用单个触摸监听器处理多个视图的点击事件以优化重复代码
嗨,我来帮你搞定这段重复代码的优化问题~你现在的四个engineView点击逻辑几乎一模一样,只是设置的engine数值不同,咱们可以通过统一管理视图、使用通用监听器的方式来简化代码,而且完全适配Fragment环境。
优化思路
核心就是把重复的视图放进集合统一管理,用同一个点击监听器处理所有点击,同时记录当前选中的视图(或对应的索引),这样既消除重复代码,后续维护也更方便。
优化后的完整代码
// Devices val devices = DeviceDAO(context).getDevicesByType(2) adapter = ShipDevicesAdapter(devices) binding.shipDevicesRecyclerView.layoutManager = LinearLayoutManager(context) binding.shipDevicesRecyclerView.adapter = adapter // 1. 定义变量保存当前选中的EngineView(替代原来的engine变量) private var selectedEngineView: ImageView? = null // 2. 把四个EngineView统一放进列表 val engineViews = listOf( binding.engineLayout.engineView1, binding.engineLayout.engineView2, binding.engineLayout.engineView3, binding.engineLayout.engineView4 ) // 3. 给所有视图设置同一个点击监听器 engineViews.forEachIndexed { index, view -> view.setOnClickListener { binding.shipDevicesRecyclerView.visibility = View.VISIBLE selectedEngineView = view // 直接保存选中的视图引用 // 如果其他地方需要用到engine数字,也可以同时保存: // selectedEngineNumber = index + 1 } } // 4. 简化Adapter的点击事件 adapter.setOnItemClickListener { val resId = Game.getResId(it.image, R.drawable::class.java) // 直接给选中的视图设置图片,不用再写一堆when判断 selectedEngineView?.setImageResource(resId) binding.shipDevicesRecyclerView.visibility = View.GONE }
关键说明
- 消除重复代码:原来的4个
setOnClickListener合并成一个循环处理,后续如果新增engineView,只需要把它加到engineViews列表里就行,不用再写重复的点击逻辑。 - 更直观的状态管理:直接保存选中的视图引用,比用数字
engine映射视图更清晰,减少出错概率。 - 适配Fragment环境:这种方式完全不依赖Activity,在Fragment里使用和Activity里一样顺畅,不用额外处理视图ID的问题。
如果你的业务逻辑确实需要保留engine数字(比如其他地方要用到这个编号),可以额外定义一个private var selectedEngineNumber: Int = 0,在forEachIndexed的点击事件里设置selectedEngineNumber = index + 1,后续在Adapter里还是可以用when判断,但直接操作视图的方式依然是更简洁的选择。
备注:内容来源于stack exchange,提问作者Delek
相关产品推荐
相关产品推荐

