【问题标题】:Sorting RecyclerView Items With A DATABASE使用数据库对 RecyclerView 项目进行排序
【发布时间】:2018-04-08 09:51:02
【问题描述】:

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

我在这种情况下使用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,但显然它对我不起作用。有什么建议吗?

【问题讨论】:

    标签: java sql database android-recyclerview itemtouchhelper


    【解决方案1】:

    使用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

    【讨论】:

    • 我想我不够清楚......我试图让用户能够通过拖放对他最喜欢的歌曲进行排序,然后将当前列表保存在数据库中......
    • 排序列表效果很好。只是它不会保存在数据库中,这意味着在我对列表进行排序并播放歌曲后,会播放上一首歌曲。
    • 从表中删除所有数据,将数据保存在表中的新排序列表中
    【解决方案2】:

    使用本教程(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
    }
    

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

    【讨论】:

      猜你喜欢
      • 2020-12-09
      • 2023-03-14
      • 2015-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-06
      • 1970-01-01
      • 2021-06-13
      相关资源
      最近更新 更多