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

如何将Adapter数据传递至Activity?解决已完成任务数同步问题

问题解决步骤

1. 修复TodoAdapter中的逻辑错误

你的Adapter同时设置了setOnCheckedChangeListener和setOnClickListener,会导致事件冲突,且状态更新、列表操作逻辑存在问题,先修改这部分:

class TodoAdapter(
    private var todos: MutableList<Todo>, 
    private var dones: MutableList<Todo>,
    private val onDoneListChanged: () -> Unit // 添加回调,通知外部列表变化
): RecyclerView.Adapter<TodoAdapter.TodoViewHolder>() {

    class TodoViewHolder(ItemTodoBinding: ItemTodoBinding): RecyclerView.ViewHolder(ItemTodoBinding.root)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TodoViewHolder {
        val layoutInflater = LayoutInflater.from(parent.context)
        val itemTodoBinding = ItemTodoBinding.inflate(layoutInflater, parent, false)
        return TodoViewHolder(itemTodoBinding)
        // 移除原代码中重复的return语句
    }

    private fun toggleStrikeThrough(tvTodoTitle: TextView, isChecked:Boolean){
        if(isChecked){
            tvTodoTitle.paintFlags = tvTodoTitle.paintFlags or STRIKE_THRU_TEXT_FLAG
        }else{
            tvTodoTitle.paintFlags = tvTodoTitle.paintFlags and STRIKE_THRU_TEXT_FLAG.inv()
        }
    }

    override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {
        val curTodo = todos[position]
        holder.itemView.apply{
            val tvTodoTitle = findViewById<TextView>(R.id.tvTodoTitle)
            val tvTodoDate = findViewById<TextView>(R.id.tvTodoDate)
            val cbDone = findViewById<CheckBox>(R.id.cbDone)

            tvTodoTitle.text = curTodo.title
            tvTodoDate.text = curTodo.date
            cbDone.isChecked = curTodo.isChecked
            toggleStrikeThrough(tvTodoTitle, curTodo.isChecked)

            // 整合监听逻辑,避免事件冲突
            cbDone.setOnCheckedChangeListener { _, isChecked ->
                toggleStrikeThrough(tvTodoTitle, isChecked)
                curTodo.isChecked = isChecked // 直接赋值为当前选中状态,无需取反

                if(isChecked){
                    // 选中时将任务移至已完成列表
                    todos.remove(curTodo)
                    dones.add(curTodo)
                    notifyItemRemoved(position) // 用精确的通知提升性能
                    onDoneListChanged() // 触发回调通知MainActivity更新按钮
                } else {
                    // 取消选中时将任务移回待办列表(可选逻辑,按需保留)
                    dones.remove(curTodo)
                    todos.add(curTodo)
                    notifyItemInserted(todos.size - 1)
                    onDoneListChanged()
                }
            }
        }
    }

    override fun getItemCount(): Int = todos.size
}

2. 修改MainActivity,接收回调并更新按钮文本

在MainActivity中初始化Adapter时传入回调,确保每次已完成列表变化时更新按钮显示:

class MainActivity : AppCompatActivity() {

    private lateinit var todoAdapter:TodoAdapter
    private lateinit var binding: ActivityMainBinding
    private var todos: MutableList<Todo> = mutableListOf()
    private var dones: MutableList<Todo> = mutableListOf()

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

        // 初始化Adapter并传入回调
        todoAdapter = TodoAdapter(todos, dones) {
            updateDoneButtonText()
        }
        binding.rvTodoItems.adapter = todoAdapter
        binding.rvTodoItems.layoutManager = LinearLayoutManager(this)

        binding.btnAddTodo.setOnClickListener{
            NewTaskSheet().show(supportFragmentManager,"NewTaskTag")
        }

        supportFragmentManager.setFragmentResultListener("requestKey",this){ _, bundle ->
            val newTodo = bundle.getSerializable("bundleKey") as Todo
            todos.add(newTodo)
            todoAdapter.notifyItemInserted(todos.size - 1)
            updateDoneButtonText() // 新增任务后可按需更新按钮
        }

        binding.btnTodoDone.setOnClickListener{
            val intent = Intent(this, SecondActivity::class.java)
            startActivity(intent)
        }

        // 初始化时设置一次按钮文本
        updateDoneButtonText()
    }

    // 提取更新按钮文本的方法,方便重复调用
    private fun updateDoneButtonText(){
        binding.btnTodoDone.text = "Done(${dones.size})"
    }
}

关键问题说明

  1. 按钮文本未实时更新:原代码仅在onCreate中设置一次按钮文本,后续已完成列表变化时未重新赋值,导致始终显示0。通过updateDoneButtonText方法,在列表变化时调用即可实时更新数量。
  2. Adapter事件冲突:同时设置两种点击监听会导致触发逻辑混乱,整合为一个监听即可解决。
  3. 列表变化感知:通过给Adapter添加回调接口,让MainActivity能感知已完成列表的变化,从而触发按钮文本更新。

内容的提问来源于stack exchange,提问作者Владислава Черкасова

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 11:08:19