Kotlin中如何为同一个setOnClickListener实现点赞/取消点赞双功能?
问题根因
你犯了两个核心逻辑错误:
- 混淆了变量用途:代码中的
fbtoken是你存储的用户登录凭证,仅用于标记用户是否登录,和当前内容是否被点赞完全是两个无关的状态,你错误地用登录状态判断是否已经点赞。 - 变量值不匹配:用户登录成功后你存入
SharedPreferences的UserToken是后端下发的真实凭证字符串,永远不会等于"true",所以你修改后的内层if (fbtoken.equals("true"))分支永远无法触发,每次点击都会走else分支调用取消点赞接口。
修复方案
1. 新增点赞状态字段
在你的列表数据源实体类中新增独立的isLiked布尔字段,初始值根据接口返回的当前内容点赞状态赋值,每个列表项对应单独的状态。
2. 修正点击逻辑
保持外层的登录校验逻辑不变,登录验证通过后,判断当前列表项的isLiked状态执行对应操作:
like.setOnClickListener { val sharedPreference2 = context?.getSharedPreferences("isLogin", Context.MODE_PRIVATE) val fbtoken = sharedPreference2?.getString("UserToken", "false") if(fbtoken.equals("false")) { // 原有未登录弹窗逻辑保持不变 val builder = AlertDialog.Builder(context).create() val layoutInflator = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater val dialogView = layoutInflator.inflate(R.layout.alert_reg, null) val goreg = dialogView.findViewById<TextView>(R.id.confirmation_reg) val cancel = dialogView.findViewById<TextView>(R.id.cancel_reg) builder.setCancelable(false) builder.setView(dialogView) goreg?.setOnClickListener { val intent = Intent(context, SignupActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK context.startActivity(intent) } cancel?.setOnClickListener { builder.dismiss() } builder.show() } else { // 登录验证通过,判断当前项的点赞状态 val currentItem = yourListData[position] // yourListData替换为你的列表数据源变量名 if (!currentItem.isLiked) { // 未点赞,调用点赞接口 postLike(position, it.context) like.setImageResource(R.drawable.liked) currentItem.isLiked = true } else { // 已点赞,调用取消点赞接口 deleteLike(position, it.context) like.setImageResource(R.drawable.like) currentItem.isLiked = false } } }
可选优化
上述写法为乐观更新,若要避免接口请求失败导致UI和实际状态不一致,可在postLike和deleteLike的接口请求成功回调中再修改isLiked字段和按钮图标。
内容的提问来源于stack exchange,提问作者Enigma
相关产品推荐
相关产品推荐

