从onBindViewHolder中的setOnClickListener运行Room DAO

时间:2018-10-08 18:58:58

标签: android kotlin

我有一个recyclerview,它显示我的sql数据的cardview。现在,我想向每张卡添加操作,以便能够删除数据并更新视图。

我在适配器的onBindViewHolder中添加了OnClickListener。该代码运行,但不会删除数据。如果再次运行相同的单击动作,则会得到“ lateinit属性mWorkerHandler尚未初始化”。这是我的监听器代码。我知道这可能不正确,但这是我到目前为止的尝试:

    holder.deleteButton.setOnClickListener{
        var mDb: TaskDatabase? = null
        mDb = TaskDatabase.getInstance(this.mInflater.context)
        lateinit var mDbWorkerThread: DbWorkerThread
        mDbWorkerThread = DbWorkerThread("dbWorkerThread2")
        mDbWorkerThread.start()
        val task = Runnable { mDb?.taskDao()?.deleteById(holder.id as Int) }
        mDbWorkerThread.postTask(task)
        TaskDatabase.destroyInstance()
        mDbWorkerThread.quit()
    }

我完全不确定数据库的上下文。我不确定的第二部分是线程。也许总有更好的方法?

2 个答案:

答案 0 :(得分:1)

在删除代码后,您无法在适应对象上调用notify数据集changed以使其知道更新列表。我不想将这样的代码放在回收视图适配器的onbindviewholder()函数上。在您的活动中创建函数以从db中删除该条目,一旦删除该条目,请在适配器上调用notifydatasetchanged。从db的后台线程返回时,不要忘记在主线程上调用它。 建立一个接口,将要从适配器中删除的项目传递给活动,然后在其中写入删除逻辑。

更新

您可以这样做:

声明界面:

public interface MyInterface{
   public void foo(int deleteThisId);
}

让您的活动实现它:

public class MyActivity extends Activity implements MyInterface{

//Somewhere in on create where you init the adapter
    adapter = MyAdapter(this); // where this is the instance for the interface which will be used in adapter

    public void foo(int deleteThisId){
        //do stuff with deleteThisId
        //when finished with delete operation 
        adapter.notifyDatasetChanged();
    }

}

然后将您的活动传递给MyAdater:

public MyAdapter extends RecyclerView.Adapter<>{
private MyInterface listener;

public MyAdapter(MyInterface listener){
    this.listener = listener;
}
}

在适配器的onBindViewHolder()的onClick列表器中,当您需要调用该Activity方法时:

listener.foo(idToBeDeleted);

答案 1 :(得分:0)

@Brandon Bearden, 这里有两件事要考虑。首先,不应在主线程中访问Room数据库。这意味着您的删除应该在后台线程上进行。并且,删除成功后,您需要通知RecyclerView适配器数据集已更改[ adapter.notifyDataSetChanged()]以反映视图中的更改。这必须在主/ UI线程上发生。请确保正确处理。