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

如何在使用Binding的RecyclerViewAdapter中调用finish()方法

如何通过更优雅的方式(替代强转Context)实现点击RecyclerView项关闭所在Activity

方案1:使用接口回调(推荐,解耦且安全)

这种方式让Adapter只负责触发点击事件,具体的关闭逻辑由宿主Activity自行处理,完全规避了Context强转的风险,也符合单一职责原则。

修改Adapter代码:

class MyAdapter(var users: List<User>, private val onItemClick: () -> Unit) : RecyclerView.Adapter<MyAdapter.UserViewHolder>() {

    inner class UserViewHolder(private val binding: UserRowBinding) : RecyclerView.ViewHolder(binding.root) {

        init {
            binding.root.setOnClickListener {
                val position = adapterPosition
                if (position != RecyclerView.NO_POSITION) {
                    // 启动目标Activity
                    val intent = Intent(binding.root.context, NextActivity::class.java)
                    binding.root.context.startActivity(intent)
                    // 触发回调,交由Activity处理关闭逻辑
                    onItemClick()
                }
            }
        }
    }

    // 实现Adapter核心方法
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
        val binding = UserRowBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return UserViewHolder(binding)
    }

    override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
        val user = users[position]
        // 绑定数据到Item布局(比如 holder.binding.user = user,若使用Data Binding变量绑定)
    }

    override fun getItemCount() = users.size
}

修改MyActivity代码:

class MyActivity : AppCompatActivity() {

    lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val adapter = MyAdapter(some_array_Of_users) {
            // 在Activity内部直接调用finish()
            finish()
        }
        binding.recyclerView.adapter = adapter
    }
}

方案2:安全遍历Context层级获取Activity(无需强转)

如果不想用回调,也可以通过遍历Context的包装层级,安全定位到对应的Activity实例,避免直接强转可能引发的ClassCastException:

在ViewHolder的点击事件中修改:

binding.root.setOnClickListener {
    val intent = Intent(binding.root.context, NextActivity::class.java)
    binding.root.context.startActivity(intent)

    // 安全查找Activity实例
    var currentContext = binding.root.context
    while (currentContext is ContextWrapper) {
        if (currentContext is AppCompatActivity) {
            currentContext.finish()
            break
        }
        currentContext = currentContext.baseContext
    }
}

为什么推荐方案1?

  • 解耦性强:Adapter无需依赖具体的Activity类型,复用性更高
  • 安全性高:彻底避免了类型转换异常的风险
  • 职责清晰:Adapter只负责列表展示与点击触发,业务逻辑(关闭Activity)由宿主处理,符合单一职责设计原则

内容的提问来源于stack exchange,提问作者Lance Samaria

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 03:15:17