You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用单个触摸监听器处理多个视图的点击事件以优化重复代码

如何使用单个触摸监听器处理多个视图的点击事件以优化重复代码

嗨,我来帮你搞定这段重复代码的优化问题~你现在的四个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 10:24:34