RecyclerView更全解析之 - 仿支付寶側(cè)滑刪除和拖動(dòng)排序

1.概述


這是春節(jié)前的最后一篇分享技術(shù)的博客了,接下來(lái)的時(shí)間需要去完善視頻講解,至于今年都干了哪些事有什么成就吹牛的這里就不多說(shuō)了,聲明一下圖片資源我是盜用的別人的。這是最后一期分享RecyclerView了,我們直接看這一期需要分享的效果:
  
  

這里寫圖片描述

  
  
  視頻講解http://pan.baidu.com/s/1jIlwl4E

相關(guān)文章:
  
  RecyclerView更全解析之 - 基本使用和分割線解析
  
  RecyclerView更全解析之 - 打造通用的萬(wàn)能Adapter
  
  RecyclerView更全解析之 - 為它優(yōu)雅的添加頭部和底部
  
  RecyclerView更全解析之 - 打造通用的下拉刷新上拉加載
  
  RecyclerView更全解析之 - 仿支付寶側(cè)滑刪除和拖動(dòng)排序

2.基本思路


前面我們一直都是圍著RecyclerView在轉(zhuǎn),發(fā)現(xiàn)這個(gè)控件讓我們是又愛(ài)又恨,通過(guò)這幾期的分享或者說(shuō)是封裝應(yīng)該已經(jīng)讓我們喜歡上它了,那么今天我們?cè)趤?lái)看一個(gè)如此神奇的功能。我記得當(dāng)初在做ListView的拖動(dòng)排序的時(shí)候在網(wǎng)上找了各種資料,代碼量還真不是一丁點(diǎn),現(xiàn)在我們來(lái)看一下RecyclerView的拖動(dòng)排序和側(cè)滑刪除需要怎么去實(shí)現(xiàn),告訴你只需要簡(jiǎn)簡(jiǎn)單單的幾行代碼。
  實(shí)現(xiàn)這么個(gè)功能我們不需要再去繼承RecyclerView,只需要去了解ItemTouchHelper這個(gè)類即可,接下來(lái)我們就去看看都有些什么。

3.基本實(shí)現(xiàn)


3.1 實(shí)現(xiàn)側(cè)滑刪除
  ItemTouchHelper這是google給我們寫好的,專門用來(lái)處理Touch相關(guān)的一個(gè)類,我們先來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的功能側(cè)滑刪除,先上代碼再解釋:

        // 實(shí)現(xiàn)左邊側(cè)滑刪除
        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
            @Override
            public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                // 獲取觸摸響應(yīng)的方向   包含兩個(gè) 1.拖動(dòng)dragFlags 2.側(cè)滑刪除swipeFlags
                // 代表只能是向左側(cè)滑刪除,當(dāng)前可以是這樣ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT
                int swipeFlags = ItemTouchHelper.LEFT;

                // 拖動(dòng)暫不處理默認(rèn)是0
                return makeMovementFlags(0, swipeFlags);
            }

            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                return false;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {

            }
        });
        // 這個(gè)就不多解釋了,就這么attach
        itemTouchHelper.attachToRecyclerView(mRecyclerView);

ItemTouchHelper.Callback 默認(rèn)需要實(shí)現(xiàn)三個(gè)方法:

  • getMovementFlags() 獲取Touch的響應(yīng)方向,包含兩個(gè) 1.拖動(dòng)dragFlags 2.側(cè)滑刪除swipeFlags,都可以是上下左右,上面事例沒(méi)有處理拖動(dòng)所以傳的是0,側(cè)滑給的是ItemTouchHelper.LEFT,所以待會(huì)效果是向左滑動(dòng)刪除;

  • onMove() 拖動(dòng)的時(shí)候會(huì)不斷的回調(diào)這個(gè)方法,拖動(dòng)的時(shí)候肯定需要不斷的更新列表數(shù)據(jù),達(dá)到一邊拖動(dòng)列表不斷更新當(dāng)前數(shù)據(jù);

  • onSwiped() 側(cè)滑刪除之后的回調(diào)方法。

這里寫圖片描述

目前的效果可以側(cè)滑刪除但是發(fā)現(xiàn)列表不更新,而且側(cè)滑的時(shí)候不高亮,當(dāng)然如果你不想要高亮那就不處理,再來(lái)改改:

        // 實(shí)現(xiàn)左邊側(cè)滑刪除
        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
            @Override
            public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                // 獲取觸摸響應(yīng)的方向   包含兩個(gè) 1.拖動(dòng)dragFlags 2.側(cè)滑刪除swipeFlags
                // 代表只能是向左側(cè)滑刪除,當(dāng)前可以是這樣ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT
                int swipeFlags = ItemTouchHelper.LEFT;

                // 拖動(dòng)暫不處理默認(rèn)是0
                return makeMovementFlags(0, swipeFlags);
            }

            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                return false;
            }

            /**
             * 側(cè)滑刪除后會(huì)回調(diào)的方法
             */
            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                // 獲取當(dāng)前刪除的位置
                int position = viewHolder.getAdapterPosition();
                mItems.remove(position);
                // adapter 更新notify當(dāng)前位置刪除
                mAdapter.notifyDataSetChanged();
            }

            /**
             * 拖動(dòng)選擇狀態(tài)改變回調(diào)
             */
            @Override
            public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
                if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
                    // ItemTouchHelper.ACTION_STATE_IDLE 看看源碼解釋就能理解了
                    // 側(cè)滑或者拖動(dòng)的時(shí)候背景設(shè)置為灰色
                    viewHolder.itemView.setBackgroundColor(Color.GRAY);
                }
            }

            /**
             * 回到正常狀態(tài)的時(shí)候回調(diào)
             */
            @Override
            public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                // 正常默認(rèn)狀態(tài)下背景恢復(fù)默認(rèn)
                viewHolder.itemView.setBackgroundColor(0);
            }
        });
        // 這個(gè)就不多解釋了,就這么attach
        itemTouchHelper.attachToRecyclerView(mRecyclerView);
這里寫圖片描述

3.2 實(shí)現(xiàn)拖動(dòng)排序
  上面有兩個(gè)方法onSelectedChanged(),clearView()不做過(guò)多的介紹,接下來(lái)實(shí)現(xiàn)拖動(dòng)排序,還是我們?cè)谏厦娴拇a基礎(chǔ)山做一下修改,需要修改兩個(gè)方法:
  getMovementFlags() 的dragFlags參數(shù)不能傳0了,側(cè)滑的時(shí)候沒(méi)處理現(xiàn)在需要處理一下了;
  onMove() 在拖動(dòng)的時(shí)候不斷的回調(diào)改變列表的位置,不光要改變位置還要不斷的改變數(shù)據(jù)集合的列表。

        // 實(shí)現(xiàn)左邊側(cè)滑刪除 和 拖動(dòng)排序
        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
            @Override
            public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                // 獲取觸摸響應(yīng)的方向   包含兩個(gè) 1.拖動(dòng)dragFlags 2.側(cè)滑刪除swipeFlags
                // 代表只能是向左側(cè)滑刪除,當(dāng)前可以是這樣ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT
                int swipeFlags = ItemTouchHelper.LEFT;


                // 拖動(dòng)
                int dragFlags = 0;
                if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
                    // GridView 樣式四個(gè)方向都可以
                    dragFlags = ItemTouchHelper.UP | ItemTouchHelper.LEFT |
                            ItemTouchHelper.DOWN | ItemTouchHelper.RIGHT;
                } else {
                    // ListView 樣式不支持左右,只支持上下
                    dragFlags = ItemTouchHelper.UP |
                            ItemTouchHelper.DOWN;
                }

                return makeMovementFlags(dragFlags, swipeFlags);
            }

            /**
             * 拖動(dòng)的時(shí)候不斷的回調(diào)方法
             */
            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                // 獲取原來(lái)的位置
                int fromPosition = viewHolder.getAdapterPosition();
                // 得到目標(biāo)的位置
                int targetPosition = target.getAdapterPosition();
                if (fromPosition > targetPosition) {
                    for (int i = fromPosition; i < targetPosition; i++) {
                        Collections.swap(mItems, i, i + 1);// 改變實(shí)際的數(shù)據(jù)集
                    }
                } else {
                    for (int i = fromPosition; i > targetPosition; i--) {
                        Collections.swap(mItems, i, i - 1);// 改變實(shí)際的數(shù)據(jù)集
                    }
                }
                mAdapter.notifyItemMoved(fromPosition, targetPosition);
                return true;
            }

            /**
             * 側(cè)滑刪除后會(huì)回調(diào)的方法
             */
            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                // 獲取當(dāng)前刪除的位置
                int position = viewHolder.getAdapterPosition();
                mItems.remove(position);
                // adapter 更新notify當(dāng)前位置刪除
                mAdapter.notifyItemRemoved(position);
            }

            /**
             * 拖動(dòng)選擇狀態(tài)改變回調(diào)
             */
            @Override
            public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
                if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
                    // ItemTouchHelper.ACTION_STATE_IDLE 看看源碼解釋就能理解了
                    // 側(cè)滑或者拖動(dòng)的時(shí)候背景設(shè)置為灰色
                    viewHolder.itemView.setBackgroundColor(Color.GRAY);
                }
            }

            /**
             * 回到正常狀態(tài)的時(shí)候回調(diào)
             */
            @Override
            public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                // 正常默認(rèn)狀態(tài)下背景恢復(fù)默認(rèn)
                viewHolder.itemView.setBackgroundColor(0);
                ViewCompat.setTranslationX(viewHolder.itemView,0);
            }
        });
        // 這個(gè)就不多解釋了,就這么attach
        itemTouchHelper.attachToRecyclerView(mRecyclerView);

這里寫圖片描述

  
附視頻地址:http://pan.baidu.com/s/1jHW1X10

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容