Kotlin实现RecyclerView条目跳转新页面并匹配本地DB的clientId
解决RecyclerView条目跳转后的数据获取与clientId校验问题
问题2:新页面获取点击条目的本地数据库对应数据
当前通过position传递数据存在风险(数据源更新后position可能对应不同数据),更可靠的方式是传递唯一标识clientId,以下是具体修改步骤:
1. 修改Adapter的点击逻辑
调整Adapter的点击接口,直接传递Customer对象,避免依赖position:
class ClientListAdapter : RecyclerView.Adapter<ClientListAdapter.MyViewHolder>() { private lateinit var clientListener: onItemClickListener // 修改接口参数为Customer对象 interface onItemClickListener { fun onItemClick(customer: Customer) } fun setOnItemClickListener(listener: onItemClickListener) { clientListener = listener } private var customerList = emptyList<Customer>() class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val clientName: TextView = itemView.findViewById(R.id.clientTitle) val clientID: TextView = itemView.findViewById(R.id.clientId) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { val itemView = LayoutInflater.from(parent.context).inflate(R.layout.client_item, parent, false) return MyViewHolder(itemView) } override fun onBindViewHolder(holder: MyViewHolder, position: Int) { val customerSelected = customerList[position] holder.clientName.text = customerSelected.name holder.clientID.text = customerSelected.clientId // 绑定数据时设置点击监听,传递当前Customer对象 holder.itemView.setOnClickListener { clientListener.onItemClick(customerSelected) } } fun setData(customer: List<Customer>) { this.customerList = customer notifyDataSetChanged() } override fun getItemCount(): Int { return customerList.size } }
2. 修改ClientActivity的跳转逻辑
在点击回调中传递clientId到目标页面:
adapter.setOnItemClickListener(object : ClientListAdapter.onItemClickListener{ override fun onItemClick(customer: Customer) { Log.d("testar", "点击客户:${customer.name},clientId:${customer.clientId}") val intent = Intent(this@ClientActivity, InfoActivity::class.java) // 传递唯一标识clientId intent.putExtra("CLIENT_ID", customer.clientId) startActivity(intent) } })
3. 在InfoActivity中查询数据库数据
首先确保CustomerViewModel包含根据clientId查询数据的方法:
class CustomerViewModel(application: Application) : AndroidViewModel(application) { // 假设你的Dao已实现该查询方法 fun getCustomerByClientId(clientId: String): LiveData<Customer?> { return customerDao.getCustomerByClientId(clientId) } }
然后修改InfoActivity获取并展示数据:
class InfoActivity : AppCompatActivity() { private lateinit var binding: ActivityInfoBinding private lateinit var customerViewModel: CustomerViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityInfoBinding.inflate(layoutInflater) setContentView(binding.root) customerViewModel = ViewModelProvider(this)[CustomerViewModel::class.java] val clientId = intent.getStringExtra("CLIENT_ID") ?: "" Log.d("WERA", "收到的clientId:$clientId") // 观察数据库查询结果并展示 customerViewModel.getCustomerByClientId(clientId).observe(this) { customer -> customer?.let { binding.tvClientName.text = it.name binding.tvClientId.text = it.clientId // 执行clientId校验逻辑 validateClientId(clientId, it) } ?: run { Toast.makeText(this, "未找到该客户数据", Toast.LENGTH_SHORT).show() } } } }
问题3:通过clientId校验RecyclerView点击条目与本地DB中数据的一致性
在InfoActivity中添加校验逻辑,对比传递的clientId与数据库返回数据的clientId是否一致:
private fun validateClientId(originalClientId: String, dbCustomer: Customer) { if (originalClientId == dbCustomer.clientId) { Log.d("VALIDATE", "clientId校验通过,数据一致") // 校验通过,正常展示逻辑 } else { Log.d("VALIDATE", "clientId校验失败,数据不一致") Toast.makeText(this, "数据校验失败,请重试", Toast.LENGTH_SHORT).show() finish() // 校验失败可返回上一页 } }
额外优化建议
- 移除Adapter中重复的点击监听,避免逻辑冲突
- 使用
LiveData确保数据库数据更新时UI自动同步 - 对空
clientId等异常情况做处理,提升代码健壮性
内容的提问来源于stack exchange,提问作者Lagos77
相关产品推荐
相关产品推荐

