在 Kotlin Lambda 中调用 RxJava Single
Calling an RxJava Single In Kotlin Lambda
我正在尝试修改新的 Room 库以将其与 RxJava 配对。
我找到了一种使用 Single
在后台线程上插入项目的方法,在 activity:
中
Single.fromCallable { AppDatabase.getInMemoryDatabase(this).taskDao().insertAll(task) }
.subscribeOn(Schedulers.newThread())
.subscribe()
现在,我有一个带有任务的 RecyclerView,它有一个复选框,您可以使用它来将项目标记为完成或未完成。我想要做的是每次 checked/unchecked 时更新项目。我将粘贴整个 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 中这样做?我需要以某种方式将 Single 拉到外面吗?
我还没有测试过,但这应该可以工作
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 functionality or Room
我会使用 Observable.create
创建 Observable,使用 lambda 保存发射器,然后使用 setOnCheckedChangeListener
传递下一个项目
emitter.onNext()
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])
}
}
}
我正在尝试修改新的 Room 库以将其与 RxJava 配对。
我找到了一种使用 Single
在后台线程上插入项目的方法,在 activity:
Single.fromCallable { AppDatabase.getInMemoryDatabase(this).taskDao().insertAll(task) }
.subscribeOn(Schedulers.newThread())
.subscribe()
现在,我有一个带有任务的 RecyclerView,它有一个复选框,您可以使用它来将项目标记为完成或未完成。我想要做的是每次 checked/unchecked 时更新项目。我将粘贴整个 ViewHolder 以完成,但要特别注意 bindTask()
:
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 中这样做?我需要以某种方式将 Single 拉到外面吗?
我还没有测试过,但这应该可以工作
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 functionality or Room
我会使用 Observable.create
创建 Observable,使用 lambda 保存发射器,然后使用 setOnCheckedChangeListener
传递下一个项目
emitter.onNext()
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])
}
}
}