Android fundamentals 10.1 Part B: Deleting data from a Room database
Task 1: Initialize data only if the database is empty
1.1 Add a method to the DAO to get a single word
- In the
WordDao
interface, add a method to get any word:
@Query("SELECT * from word_table LIMIT 1")
Word[] getAnyWord();
1.2 Update the initialization method to check whether data exists
PopulateDBAsync
is an inner class in WordRoomDatbase
. In PopulateDBAsync
, update the doInBackground()
method to check whether the database has any words before initializing the data:
@Override
protected Void doInBackground(final Void... params) {
// If we have no words, then create the initial list of words
if (mDao.getAnyWord().length < 1) {
for (int i = 0; i <= words.length - 1; i++) {
Word word = new Word(words[i]);
mDao.insert(word);
}
}
return null;
}
- Run your app and add several new words. Close the app and restart it. You should see the new words that you added, as the words should now persist when the app is closed and opened again.
Task 2: Delete all words
2.1 Add deleteAll() to the WordDao interface and annotate it
- In
WordDao
, check that thedeleteAll()
method is defined and annotated with the SQL that runs when the method executes:
@Query("DELETE FROM word_table")
void deleteAll();
2.2 Add deleteAll() to the WordRepository class
- In
WordRepository
, definedeleteAllWordsAsyncTask
as an inner class. ImplementdoInBackground()
to delete all the words by callingdeleteAll()
on the DAO :
private static class deleteAllWordsAsyncTask extends AsyncTask<Void, Void, Void> {
private WordDao mAsyncTaskDao;
deleteAllWordsAsyncTask(WordDao dao) {
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(Void... voids) {
mAsyncTaskDao.deleteAll();
return null;
}
}
- In the
WordRepository
class, add thedeleteAll()
method to invoke theAsyncTask
that you defined.
public void deleteAll() {
new deleteAllWordsAsyncTask(mWordDao).execute();
}
2.3 Add deleteAll() to the WordViewModel class
Make the deleteAll()
method available to the MainActivity
by adding it to the WordViewModel
.
- In the
WordViewModel
class, add thedeleteAll()
method:
public void deleteAll() {mRepository.deleteAll();}
Task 3: Add an Options menu item to delete all data
3.1 Add the Clear all data menu option
- In
menu_main.xml
, change the menu optiontitle
andid
, as follows:
<item
android:id="@+id/clear_data"
android:orderInCategory="100"
android:title="@string/clear_all_data"
app:showAsAction="never" />
- In
MainActivity
, implement theonOptionsItemSelected()
method to invoke thedeleteAll()
method on theWordViewModel
object.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.clear_data) {
// Add a toast just for confirmation
Toast.makeText(this, "Clearing the data...",
Toast.LENGTH_SHORT).show();
// Delete the existing data
mWordViewModel.deleteAll();
return true;
}
return super.onOptionsItemSelected(item);
}
- Run your app. In the Options menu, select Clear all data. All words should disappear.
- Restart the app. (Restart it from your device or the emulator; don’t run it again from Android Studio) You should see the initial set of words.
Task 4: Delete a single word
4.1 Add deleteWord() to the DAO and annotate it
- In
WordDao
, add thedeleteWord()
method:
@Delete
void deleteWord(Word word);
4.2 Add deleteWord() to the WordRepository class
- In
WordRepository
, define anotherAsyncTask
calleddeleteWordAsyncTask
as an inner class. ImplementdoInBackground()
to delete a word by callingdeleteWord()
on the DAO:
private static class deleteWordAsyncTask extends AsyncTask<Word, Void, Void> {
private WordDao mAsyncTaskDao;
deleteWordAsyncTask(WordDao dao) {
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(final Word... params) {
mAsyncTaskDao.deleteWord(params[0]);
return null;
}
}
- In
WordRepository
, add thedeleteWord()
method to invoke theAsyncTask
you defined.
public void deleteWord(Word word) {
new deleteWordAsyncTask(mWordDao).execute(word);
}
4.3 Add deleteWord() to the WordViewModel class
To make the deleteWord()
method available to other classes in the app, in particular, MainActivity,
add it to WordViewModel
.
- In
WordViewModel
, add thedeleteWord()
method:
public void deleteWord(Word word) {mRepository.deleteWord(word);}
Task 5: Enable users to swipe words away
5.1 Enable the adapter to detect the swiped word
- In
WordListAdapter
, add a method to get the word at a given position.
public Word getWordAtPosition (int position) {
return mWords.get(position);
}
- In
MainActivity
, inonCreate()
, create theItemTouchHelper
. Attach theItemTouchHelper
to theRecyclerView
.
// Add the functionality to swipe items in the
// recycler view to delete that item
ItemTouchHelper helper = new ItemTouchHelper(
new ItemTouchHelper.SimpleCallback(0,
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
@Override
public boolean onMove(RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder,
RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder,
int direction) {
int position = viewHolder.getAdapterPosition();
Word myWord = adapter.getWordAtPosition(position);
Toast.makeText(MainActivity.this, "Deleting " +
myWord.getWord(), Toast.LENGTH_LONG).show();
// Delete the word
mWordViewModel.deleteWord(myWord);
}
});
helper.attachToRecyclerView(recyclerView);
Things to notice in the code:
onSwiped()
gets the position of the ViewHolder
that was swiped:
int position = viewHolder.getAdapterPosition();
Given the position, you can get the word displayed by the ViewHolder
by calling the getWordAtPosition()
method that you defined in the adapter:
Word myWord = adapter.getWordAtPosition(position);
Delete the word by calling deleteWord()
on the WordViewModel
:
mWordViewModel.deleteWord(myWord);
Now run your app and delete some words
- Run your app. You should be able to delete words by swiping them left or right.
Thank you :))