使用数据库对RecyclerView项目进行排序

时间:2018-04-08 09:51:02

标签: java sql database android-recyclerview itemtouchhelper

我目前正在制作一款音乐应用程序,该应用程序有一首"收藏的歌曲"标签。 我试图实现一种工具,允许用户使用拖放功能对存储在数据库中的喜爱歌曲进行排序。下降。

我在这种情况下使用ItemTouchHelper,但我的搜索都没有产生适用于数据库的解决方案。

**我的列表从数据库填充**

FavoritesPresenter.class

        ItemTouchHelper.SimpleCallback simpleCallback =
                new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN, 0) {

                    @Override
                    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                        mRecyclerView.notifyItemMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition());
                        return true;
                    }

                    @Override
                    public void onMoved(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, int fromPos, RecyclerView.ViewHolder target, int toPos, int x, int y) {
                        super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y);

                    }

DataBase.class

int updateOrder(long id, int newPos) {
    ContentValues cv = new ContentValues();
    cv.put(DataBaseOpenHelper.COLUMN_ORDER, newPos);

    String where = DataBaseOpenHelper.COLUMN_ID + "=?";
    String[] whereArgs = {String.valueOf(id)};

    return getWritable().update(DataBaseOpenHelper.TABLE_NAME_FAVORITE, cv, where, whereArgs);
}

我已经尝试过这个"解决方案" here,但显然它不适合我。有什么建议吗?

2 个答案:

答案 0 :(得分:0)

使用Android recyclelerview进行拖放排序非常简单,无需使用第三方库

private final OnStartDragListener mDragStartListener;

public RecyclerListAdapter(OnStartDragListener dragStartListener) {
mDragStartListener = dragStartListener;
// ...
}@Override
public void onBindViewHolder(final ItemViewHolder holder, 
int position) {
// ... holder.handleView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (MotionEventCompat.getActionMasked(event) == 
MotionEvent.ACTION_DOWN) {
mDragStartListener.onStartDrag(holder);
}
return false;
}
});
}

有关详细信息,请查看以下帖子

https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-6a6f0c422efd

答案 1 :(得分:0)

使用本教程(由Fazel提及): https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-6a6f0c422efd

我创建了一个对我有用的解决方案。我不知道这是否是正确的方法,也许有人可以改善这个答案。

onItemMove()和onMoved()都在我仍在拖动项目的同时被调用。 clearView()仅被调用一次。当我使用Firestore作为数据库时,我真的只想在拖动完成后更新项目。

我正在更新类别,因此我有一个CategoryFirestoreAdapter来扩展FirestoreAdapter。我保存在数据库中的排序顺序从1(不是0)开始。

ItemTouchHelperAdapter

public interface ItemTouchHelperAdapter {

    boolean onItemMove(int fromPosition, int toPosition);

    void onItemDismiss(int position);

    void clearView(); //added this
}

SimpleItemTouchHelperCallback

@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {

    super.clearView(recyclerView, viewHolder);

    viewHolder.itemView.setAlpha(ALPHA_FULL);

    if (viewHolder instanceof ItemTouchHelperViewHolder) {
        // Tell the view holder it's time to restore the idle state
        ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
        itemViewHolder.onItemClear();
    }
    mAdapter.clearView(); //add this so the method gets called in the CategoryFirestoreAdapter
}

CategoryFirestoreAdapter

public class CategoryFirestoreAdapter
    extends FirestoreAdapter<CategoryFirestoreAdapter.ViewHolder>
    implements ItemTouchHelperAdapter {

@Override
public void clearView() {

    //Update the database here for the items that have moved.

    FirebaseFirestore db = FirebaseFirestore.getInstance();
    ArrayList<DocumentSnapshot> snapshots = getAllItems();

    db.runTransaction(new Transaction.Function<Object>() {

        @Nullable
        @Override
        public Object apply(@NonNull Transaction transaction) {

            for (int i = 0; i < snapshots.size(); i++) {

                DocumentSnapshot snapshot = snapshots.get(i);
                DocumentReference docRef = db.collection("categories").document(snapshot.getId());
                Category category = snapshot.toObject(Category.class);

                Integer sortOrder = category.getSortOrder();
                Integer newSortOrder = i+1;

                if ((i + 1) != sortOrder) {
                    //only update items that have changed.
                    transaction.update(docRef, "sortOrder", newSortOrder); //sortOrder hardcoded - fix this
                }
            }
            return null;
        }
    });
} ....

FirestoreAdapter

protected void onDocumentModified(DocumentChange change) {

//    I changed this as it was moving things around again after updating the db.  
//    I am not sure why, and this may need improving, but this is working for me.

//    Dont handle position changes, just updates.
//    if (change.getOldIndex() == change.getNewIndex()) {
//        // Item changed but remained in same position
//        mSnapshots.set(change.getOldIndex(), change.getDocument());
//        notifyItemChanged(change.getOldIndex());
//    } else {
//        // Item changed and changed position
        mSnapshots.remove(change.getOldIndex());
        mSnapshots.add(change.getNewIndex(), change.getDocument());
//        notifyItemMoved(change.getOldIndex(), change.getNewIndex());
        notifyItemChanged(change.getNewIndex()); //added
        notifyItemChanged(change.getOldIndex()); //added
//    }
}

protected ArrayList<DocumentSnapshot> getAllItems() {
    return mSnapshots;
}