Запуск DAO из setOnClickListener в onBindViewHolder - PullRequest
0 голосов
/ 08 октября 2018

У меня есть просмотрщик, который отображает данные моей карты sql.Теперь я хочу добавить действия к каждой карточке, чтобы иметь возможность удалять данные и обновлять представление.

Я добавил OnClickListener в моем onBindViewHolder в моем адаптере.Код выполняется, но он не удаляет данные.Если я снова запускаю то же действие, то получаю сообщение «Свойство 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 голосов
/ 08 октября 2018

Вы не можете вызывать команду notify dataset между адаптированными, чтобы сообщить об обновлении списка после удаления кода.Я бы не хотел помещать подобный код в функцию onbindviewholder () адаптера представления переработчика.Сделайте функцию в своей деятельности, чтобы удалить запись из базы данных, после того, как она удалена, вызовите 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;
}
}

И в списке onClick onBindViewHolder () в адаптере, когда вам нужно вызвать этот метод Activity:

listener.foo(idToBeDeleted);
0 голосов
/ 08 октября 2018

@ Брэндон Бирден, Здесь нужно учитывать две основные вещи.Во-первых, база данных Room не должна быть доступна в главном потоке.Это означает, что ваше удаление должно произойти в фоновом потоке.А после успешного удаления необходимо сообщить адаптеру RecyclerView, что набор данных был изменен [ adapter.notifyDataSetChanged () ], чтобы отразить изменения в представлении.Это должно происходить в основном потоке / пользовательском интерфейсе.Пожалуйста, убедитесь, что это обрабатывается правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...