2

我目前正在开发一个具有“最喜欢的歌曲”标签的音乐应用程序。我正在尝试实现一个工具,该工具允许用户使用拖放对存储在数据库中的他们喜欢的歌曲进行排序。

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

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

收藏夹Presenter.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);

                    }

数据库类

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);
}

我在这里尝试过这个“解决方案” ,但显然它对我不起作用。有什么建议么 ?

4

2 回答 2

0

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

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

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

我正在更新类别,所以我有一个扩展 FirestoreAdapter 的 CategoryFirestoreAdapter。我保存在数据库中的排序顺序从 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
}

类别FirestoreAdapter

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;
        }
    });
} ....

Firestore适配器

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;
}
于 2018-09-06T04:50:27.923 回答
0

使用 Android recyclerview 拖放排序很简单,无需使用第三方库

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

于 2018-04-08T10:10:53.373 回答