在Kotlin Lambda中调用一个RxJava单身人士

我正在尝试修改新的房间库与RxJava配对。

我已经找到了一种方法来使用Single来插入后台线程中的项目,就像这样,在一个activity中:

 Single.fromCallable { AppDatabase.getInMemoryDatabase(this).taskDao().insertAll(task) } .subscribeOn(Schedulers.newThread()) .subscribe() 

现在,我有一个RecyclerView任务,有一个复选框,您可以用来标记项目是否完成。 我想要做的是每次检查/取消选中时更新项目。 我将粘贴整个ViewHolder来完成,但是请特别注意bindTask()的lambda:

 inner class TaskViewHolder(view: View?) : RecyclerView.ViewHolder(view) { val descriptionTextView = view?.findViewById(R.id.task_description) as? TextView val completedCheckBox = view?.findViewById(R.id.task_completed) as? CheckBox fun bindTask(task: Task) { descriptionTextView?.text = task.description completedCheckBox?.isChecked = task.completed completedCheckBox?.setOnCheckedChangeListener { _, isChecked -> tasks[adapterPosition].completed = isChecked Single.fromCallable { itemView.context.taskDao().update(tasks[adapterPosition]) } .subscribeOn(Schedulers.newThread()) .subscribe() } } } 

这适用于我检查的第一个项目,但之后,我无法点击任何其他复选框。 我以为Single会自我毁灭,但也许我不能在lambda里面做这个? 我是否需要以某种方式将“单身”拉出来?

我会使用Observable.create创建Observable,使用lambda保存该发射器,并使用emitter.onNext()传递setOnCheckedChangeListener下一个项目。

 class TaskViewHolder(view: View) : RecyclerView.ViewHolder(view) { private lateinit var emitter: ObservableEmitter<Task> private val disposable: Disposable = Observable.create(ObservableOnSubscribe<Task> { e -> emitter = e }) .subscribeOn(Schedulers.newThread()) .observeOn(Schedulers.newThread()) .subscribe({ itemView.context.taskDao().update(it) }) val descriptionTextView = view?.findViewById(R.id.task_description) as? TextView val completedCheckBox = view?.findViewById(R.id.task_completed) as? CheckBox fun bindTask(task: Task) { descriptionTextView?.text = task.description completedCheckBox?.isChecked = task.completed completedCheckBox?.setOnCheckedChangeListener { _, isChecked -> tasks[adapterPosition].completed = isChecked emitter.onNext(tasks[adapterPosition]) } } } 

我没有测试过,但这应该工作

 class TaskViewHolder(view: View?) : RecyclerView.ViewHolder(view) { val descriptionTextView: TextView? = null val completedCheckBox: CheckBox? = null fun bindTask(task: Task) { descriptionTextView?.text = task.description completedCheckBox?.isChecked = task.completed completedCheckBox?.setOnCheckedChangeListener { _, isChecked -> tasks[adapterPosition].completed = isChecked itemView.context.taskDao().update(tasks[adapterPosition]) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ changeCount -> Timber.i("%,d item(s) updated", changeCount) }, { error -> Timber.e(error, "update failed") }) } } } interface TaskDao { fun update(task: Task): Flowable<Int> } 

而不是创建一个新的Single我使用RxJava功能或房间