Following some articles, I am trying to create an android app with the following:
recyclerview
which fetches data from room database using live data.Features in recyclerview:
Referred articles:
My problem:
Data reordering is not updated in the room library.
Note:
I am using an attribute for data ordering
Please drop a comment if code of a particular file is required.I am not sure which code to post.
MainFragment.java (Code to reorder data, which is not working)
// To handle recycler view item dragging
@Override
public void onItemMove(int fromPosition, int toPosition) {
// Log
Log.e(TAG, "Item moved from " + fromPosition + " to " + toPosition);
// Move the item within the recycler view
mainRecyclerViewAdapter.moveItem(fromPosition, toPosition);
}
// To handle recycler view item drop
@Override
public void onItemDragged(int fromPosition, int toPosition) {
// Log
Log.e(TAG, "Item dragged from " + fromPosition + " to " + toPosition);
mainActivityViewModel.moveWord(fromPosition, toPosition);
}
MainActivityViewModel.java
public void moveWord(int fromPosition, int toPosition) {
// Move word
wordRepository.move(fromPosition, toPosition);
}
WordRepository.java
public void move(int from, int to) {
new moveAsyncTask(wordDao).execute(from, to);
}
// Async update task
private static class moveAsyncTask extends AsyncTask<Integer, Void, Void> {
// Dao
private WordDao asyncTaskDao;
// Constructor
moveAsyncTask(WordDao wordDao) {
// Get dao
asyncTaskDao = wordDao;
}
@Override
protected Void doInBackground(final Integer... params) {
int from = params[0];
int to = params[1];
if (from > to) {
// Move upwards
asyncTaskDao.getAllWordsBetween(to, from - 1).forEach(wordToUpdate -> {
// Update word number
wordToUpdate.decreaseSNo();
// Update word in database
update(wordToUpdate);
});
asyncTaskDao.getWordWithNo(from).forEach(wordToUpdate -> {
// Update word number
wordToUpdate.setSno(to);
// Update word in database
update(wordToUpdate);
});
} else {
// Move downwards
asyncTaskDao.getAllWordsBetween(from + 1, to).forEach(wordToUpdate -> {
// Update word number
wordToUpdate.increaseSNo();
// Update word in database
update(wordToUpdate);
});
asyncTaskDao.getWordWithNo(from).forEach(wordToUpdate -> {
// Update word number
wordToUpdate.setSno(to);
// Update word in database
update(wordToUpdate);
});
}
return null;
}
}
WordDao.java
@Query("SELECT * FROM words WHERE sno >= :low AND sno <= :high")
List<Word> getAllWordsBetween(int low, int high);
@Query("SELECT * FROM words WHERE sno == :sNo")
List<Word> getWordWithNo(int sNo);
Here is an easy approach for ordering items, used it with Room Database.
Entity Object (Model):
A column for order, type Integer:
@ColumnInfo(name = "word_order")
private Integer mOrder;
In Dao:
A query, that retrieve the largest order in column word_order
:
@Query("SELECT MAX(word_order) FROM word_table")
int getLargestOrder();
And a query that update an entire word list:
@Update(onConflict = OnConflictStrategy.REPLACE)
void update(List<WordEntity> wordEntities);
Used
MAX
SQL command to get the largest number.
In Activity (when adding new word):
Query that method getLargestOrder()
and added +1 to it, then create a new word.
In Activity (onCreate()):
Create ItemTouchHelper
to move word items, use only UP & DOWN movement:
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.UP | ItemTouchHelper.DOWN) {
});
This is a utility class to add swipe to dismiss and drag & drop support to RecyclerView. It works with a RecyclerView and a Callback class, which configures what type of interactions are enabled and also receives events when user performs these actions.
Override getMovementFlags
inside it to specified the wanted directions:
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
return makeMovementFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN,
0);
}
Override onMove
inside it to swap item positions:
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
int fromPosition = viewHolder.getAdapterPosition();
int toPosition = target.getAdapterPosition();
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(mWordEntities, i, i + 1);
int order1 = mWordEntities.get(i).getOrder();
int order2 = mWordEntities.get(i + 1).getOrder();
mWordEntities.get(i).setOrder(order2);
mWordEntities.get(i + 1).setOrder(order1);
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(mWordEntities, i, i - 1);
int order1 = mWordEntities.get(i).getOrder();
int order2 = mWordEntities.get(i - 1).getOrder();
mWordEntities.get(i).setOrder(order2);
mWordEntities.get(i - 1).setOrder(order1);
}
}
mAdapter.notifyItemMoved(fromPosition, toPosition);
return true;
}
This method where items position get updated when moved.
First, get the positions for items from the adapter.
Then, if decrement, swap the items of Entities, by passing the current item position and the new one (for user eyes).
After that, get the order the current item and the next item, and swab them and set them with setter methods (for saving them in Room later).
On the other hand, do same for increment.
Finishing, by notify the adapter items has moved (for user eyes).
Override clearView
to update Word Entities List:
@Override
public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
mWordViewModel.update(mWordEntities);
}
This method called when user drop the item. It will be suitable to update and save the entities into the Room Database.
Override onSwiped
:
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
}
This must be override by the system.
Attache ItemTouchHelper
to the RecyclerView:
itemTouchHelper.attachToRecyclerView(mRecyclerView);
You can create many ItemTouchHelper and attach them to the RecyclerView as you need.
Beware that you need to order items in RecyclerView from Biggest number to Lowest number. Hope this help you :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With