RecyclerView拖拽排序和滑动删除实现
效果圖
如何實現(xiàn)
那么是如何實現(xiàn)的呢?主要就要使用到ItemTouchHelper ,ItemTouchHelper 一個幫助開發(fā)人員處理拖拽和滑動刪除的實現(xiàn)類,它能夠讓你非常容易實現(xiàn)側(cè)滑刪除、拖拽的功能。
實現(xiàn)的代碼非常簡單我們只需要兩步:
實例化一個ItemTouchHelper
關(guān)聯(lián)到RecyclerView
恩,就是這么簡單。
構(gòu)造方法中需要一個ItemTouchHelper.Callback,ItemTouchHelper會在拖拽的時候回調(diào)Callback中相應(yīng)的方法,我們只需在Callback中實現(xiàn)自己的邏輯就可以了。
自定義一個類繼承實現(xiàn)ItemTouchHelper.Callback接口,需要實現(xiàn)以下方法:
getMovementFlags用于設(shè)置是否處理拖拽事件和滑動事件,以及拖拽和滑動操作的方向,有以下兩種情況:
如果是列表類型的RecyclerView,拖拽只有UP、DOWN兩個方向
如果是網(wǎng)格類型的則有UP、DOWN、LEFT、RIGHT四個方向
該方法需要編寫的代碼如下:
dragFlags 是拖拽標志,swipeFlags是滑動標志,我們把swipeFlags 都設(shè)置為0,暫時不考慮滑動相關(guān)操作。
如果我們設(shè)置了相關(guān)的dragFlags ,那么當我們長按item的時候就會進入拖拽并在拖拽過程中不斷回調(diào)onMove()方法,我們就在這個方法里獲取當前拖拽的item和已經(jīng)被拖拽到所處位置的item的ViewHolder,有了這2個ViewHolder,我們就可以交換他們的數(shù)據(jù)集并調(diào)用Adapter的notifyItemMoved方法來刷新item。
這里的mDatas其實就是Adapter對應(yīng)的數(shù)據(jù)集,我們在改變Item位置的同時當然不能忘了數(shù)據(jù)集需要同步的改變。
到這里,已經(jīng)可以拖拽了,基本的效果如下:
是不是很神奇,這么復(fù)雜的特效,竟然寫了幾行代碼就搞定了~
但是拖拽的時候我們拖拽的對象不能高亮顯示,這是不友好的,我們希望拖拽的Item在拖拽的過程中背景顏色加深,這樣就需要繼續(xù)重寫下面兩個方法:
我們在開始拖拽的時候給item添加一個背景色,然后在拖拽完成的時候還原:
OK,這樣就完成了Item的拖拽排序,簡單看下現(xiàn)在的效果:
更加復(fù)雜的需求
上面的代碼完成了基本功能,但實際的產(chǎn)品需要往往可能會有些不一樣,比如說,產(chǎn)品希望,有一些item可以拖拽,一些item無法拖拽,就如上圖的“更多”是無法拖拽的。這個咋辦呢?
其實在上面我們實現(xiàn)的Callback類中有一個方法我們沒有重寫:
這個方法是為了告訴ItemTouchHelper是否需要RecyclerView支持長按拖拽,默認返回是ture(即支持),理所當然我們要支持,所以我們沒有重寫,因為默認true。但是這樣做是默認全部的item都可以拖拽,怎么實現(xiàn)部分item拖拽呢,查閱isLongPressDragEnabled方法的源碼發(fā)現(xiàn),上面的注釋上寫著:
Default value returns true but you may want to disable this if you want to start dragging on a custom view touch using {@link #startDrag(ViewHolder)}.意思是如果你想自定義觸摸view,那么就使用startDrag(ViewHolder)方法。
原來如此,我們可以在item的長按事件中得到當前item的ViewHolder ,然后調(diào)用ItemTouchHelper.startDrag(ViewHolder vh)就可以實現(xiàn)拖拽了,那就這么辦:
首先我們重寫isLongPressDragEnabled返回false,我們要自己調(diào)用拖拽過程:
接著我們給RecyclerView添加item長按事件,判斷item是否是最后一個(最后一個是“更多”),不是則開始拖拽。
但是,我們都知道RecyclerView并沒有提供OnItemLongClickListener,這個問題我們已經(jīng)在上一篇推送的文章中給出了解決方案,就是使用OnItemTouchListener,然后識別觸摸手勢,這里給上傳送門:RecyclerView添加ItemClickListener的方案,我就直接使用上一篇的成果,不重復(fù)講了(這里你可以使用直接的OnItemClickListener的方案):
額外的功能
保存位置
關(guān)閉頁面以后再打開,又恢復(fù)到了初始化的位置,所以就需要保存調(diào)整的位置到本地,下次初始化的時候讀取位置。
保存位置應(yīng)該由開發(fā)者自己實現(xiàn),因為每個人本地化數(shù)據(jù)的方式都不一樣,我這里做一個簡單的實現(xiàn),使用了開源的ACache類,兩個方法,搞定:
在clearView方法(拖拽完成)中調(diào)用存儲方法,在頁面初始化數(shù)據(jù)是調(diào)用讀取方法,具體代碼文后會給出下載鏈接。
開始拖拽時震動
支付寶的拖拽網(wǎng)格在長按后開始拖拽時會有一次短時間的震動提示用戶開始拖拽了,很友好的交互,我們也加一個:
添加權(quán)限:
<uses-permission android:name="android.permission.VIBRATE" />在開始拖拽時添加下面代碼:
滑動刪除
我看到接口里面還有個onSwipe方法,沒有使用,沒錯,這個可用于滑動刪除。
僅僅需要幾行代碼實現(xiàn)滑動刪除:
恩,就這樣就行了?
還不行,還有標志位沒設(shè)置
我們針對非表格式的布局設(shè)置了swipeFlags為STRAT和END,那么LinearLayoutManager肯定是支持的,看下效果
fragment中的onCreateView和onViewCreated的區(qū)別和聯(lián)系
onViewCreated在onCreateView執(zhí)行完后立即執(zhí)行。
onCreateView返回的就是fragment要顯示的view。
參考鏈接
fragment中的onCreateView和onViewCreated的區(qū)別和聯(lián)系_百度知道
源代碼
http://download.csdn.net/detail/liaoinstan/9494601
原文鏈接
使用ItemTouchHelper輕松實現(xiàn)RecyclerView拖拽排序和滑動刪除
總結(jié)
以上是生活随笔為你收集整理的RecyclerView拖拽排序和滑动删除实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP数据库操作
- 下一篇: map的详解及常见面试题