RecyclerView滑動刪除和拖動排序

轉載:http://www.cnblogs.com/Fndroid/p/5657342.html


先看本篇內容的效果圖:

效果內容主要有三部分:

  • 長按點擊其中一個Item之後可以將其拖動到其他地方
  • 向左右滑動可以刪除某個Item
  • 長按的時候會有一個浮起的動作,放下之後會重新重新對齊

 

①先易後難,卡片浮起效果 

在Material Design中,物件的呈現是以3d的模式來進行的,也就是在原來的基礎上增加了一個Z軸來表示物體的高度。

 當我們點擊一個卡片的時候,應該給予用戶一些反饋,讓用戶知道自己在操作這個卡片,也就是觸摸反饋。觸摸效果圖的觸摸反饋是先出現水波紋,接着當卡片可以移動的時候先浮動,再開始移動,最後下落,效果如下:(浮起的動畫可能要仔細看)

 

實現:

水波紋效果使用系統提供的,因爲Demo中使用的是一個CardView來呈現內容,所以只需要給CardView加上兩個屬性即可:

android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"

 

浮起和下沉的動畫也不難,改變View的translationZ屬性即可:

複製代碼
private void pickUpAnimation(View view) {
    ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationZ", 1f, 10f);
    animator.setInterpolator(new DecelerateInterpolator());
    animator.setDuration(300);
    animator.start();
}
複製代碼

 

 

②滑動(Swipe)和移動(Move)Item

Swipe是指我們上面的左右滑動刪除,Move則是我們對Item的移動,改變列表的排序。要實現這兩個功能,需要用到一個類ItemTouchHelper,當我們構造好這個類之後,可以調用它的attachToRecyclerView方法將其綁定在某個RecyclerView中,當RecyclerView出現某些操作(滑動和移動)時,構造這個類的時候傳入的回調類會回調相應的方法,我們在這些方法中對數據集進行操作即可。

new ItemTouchHelper(new ItemTouchHelper.Callback() {
    //省略代碼
}).attachToRecyclerView(mRecyclerView);

 

接着就是重寫接口Callback的方法了,這裏需要重寫的有幾個,分別是:

  • isItemViewSwipeEnable : Item是否可以滑動
  • isLongPressDragEnable :Item是否可以長按 
  • getMovementFlags : 獲取移動標誌
  • onMove : 當一個Item被另外的Item替代時回調,也就是數據集的內容順序改變
  • onMoved : 當onMove返回true的時候回調
  • onSwiped : 當某個Item被滑動離開屏幕之後回調
  • setSelectedChange : 某個Item被長按選中會被回調,當某個被長按移動的Item被釋放時也調用
複製代碼
new ItemTouchHelper(new ItemTouchHelper.Callback() {
    private RecyclerView.ViewHolder vh;

    @Override
    public boolean isItemViewSwipeEnabled() {
        return true;
    }

    @Override
    public boolean isLongPressDragEnabled() {
        return true;
    }

    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder
            viewHolder) {
        // 拖拽的標記,這裏允許上下左右四個方向
        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT |
                ItemTouchHelper.RIGHT;
        // 滑動的標記,這裏允許左右滑動
        int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
        return makeMovementFlags(dragFlags, swipeFlags);
    }

    /*
        這個方法會在某個Item被拖動和移動的時候回調,這裏我們用來播放動畫,當viewHolder不爲空時爲選中狀態
        否則爲釋放狀態
     */
    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        super.onSelectedChanged(viewHolder, actionState);
        if (viewHolder != null) {
            vh = viewHolder;
            pickUpAnimation(viewHolder.itemView);
        } else {
            if (vh != null) {
                putDownAnimation(vh.itemView);
            }
        }
    }


    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
                          RecyclerView.ViewHolder target) {
        // 移動時更改列表中對應的位置並返回true
        Collections.swap(newsList, viewHolder.getAdapterPosition(), target
                .getAdapterPosition());
        return true;
    }

    /*
        當onMove返回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);
        // 移動完成後刷新列表
        mAdapter.notifyItemMoved(viewHolder.getAdapterPosition(), target
                .getAdapterPosition());
    }

    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        // 將數據集中的數據移除
        newsList.remove(viewHolder.getAdapterPosition());
        // 刷新列表
        mAdapter.notifyItemRemoved(viewHolder.getAdapterPosition());
    }
}).attachToRecyclerView(mRecyclerView);
複製代碼

 

這裏直接貼出代碼,並做了註釋,應該比較簡單了。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章