RecyclerView拖拽的實現(xiàn)及一些特殊需求


首先說一下關鍵點热康,在RecyclerView中實現(xiàn)拖拽排序時非常簡單地惭笑,只需要個給RecyclerView添加一個ItemTouchHelper就可以實現(xiàn),具體實現(xiàn)如下:

1.創(chuàng)建ItemTouchHelper對象并綁定

final ItemTouchHelper itemTouchHelp = new ItemTouchHelper(new CityRecycleCallBack(adapter));
itemTouchHelp.attachToRecyclerView(recyclerView);

創(chuàng)建對象時需要一個回調昼弟,我們具體看看這個回調怎么寫

2. ItemTouchHelper.Callback回調實現(xiàn)

這個回調中有許多方法蕾殴,通多對方法的實現(xiàn)就能最終實現(xiàn)拖拽效果

2.1 getMovementFlags

在這里主要設置拖拽的方向即是否可拖拽,根據(jù)布局的不同有不同的方法黄伊,如列表只有上下拖拽泪酱,網(wǎng)格只有上下左右。具體實現(xiàn)如下:

    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
            final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
            final int swipeFlags = 0;
            return makeMovementFlags(dragFlags,swipeFlags);
        } else {
            final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
            final int swipeFlags = 0;
            return makeMovementFlags(dragFlags,swipeFlags);
        }
    }

2.2 onMove

這是一個關鍵方法还最,它在我們拖動時不斷得到調用墓阀,我們要及時更新item的位置,對數(shù)據(jù)進行更新拓轻,具體實現(xiàn)如下:

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        int fromPosition = viewHolder.getAdapterPosition();
        int toPosition = target.getAdapterPosition();
        adapter.move(fromPosition,toPosition);
        return true;
    }

首先獲得起始位置和到達位置斯撮,然后交給adapter處理:

    public void move(int fromPosition,int toPosition){
        positionChange = true;
        if (fromPosition < toPosition) {
            for (int i = fromPosition; i < toPosition; i++) {
                Collections.swap(allCity, i, i + 1);
            }
        } else {
            for (int i = fromPosition; i > toPosition; i--) {
                Collections.swap(allCity, i, i - 1);
            }
        }
        notifyItemMoved(fromPosition, toPosition);
    }

類似于數(shù)組的插入,將被拖拽的item不斷插入目標位置扶叉,雖然改變的item但我們實際調整的是存放數(shù)據(jù)的list勿锅,每次插入后更新RecyclerView

2.3 onSwiped

這個是拖拽后的回調帕膜,一般不用理會,也可以根據(jù)需求實現(xiàn)一些邏輯

2.4 isLongPressDragEnabled

默認情況下實現(xiàn)的時長按開始拖拽溢十,如果像我示例中那樣點擊某個區(qū)域就開始拖拽垮刹,或者指定某些模塊不可拖拽時,這個方法要返回false张弛。如果都是長按拖拽就要返回true

2.5 onSelectedChanged

這個是在謀和item被選中開始拖拽時的回調荒典,可以像我那樣修改選中的item透明度或者震動一下等都是常見的處理:

    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        super.onSelectedChanged(viewHolder, actionState);
        if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
            viewHolder.itemView.setAlpha(0.5f);
            viewHolder.itemView.setBackgroundColor(0);
        }
    }

2.6 clearView

這個是松開后的回調,一般要將item恢復原樣:

    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        viewHolder.itemView.setAlpha(1);
    }

3.特殊情況的處理

3.1 按住某塊區(qū)域就開始拖拽

如開頭GIF圖中所示乌庶,點擊item的拖拽圖標就可以進行拖拽种蝶,同時禁止長按拖拽的邏輯,首先isLongPressDragEnabled要返回false:

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

之后對拖拽圖標進行觸摸監(jiān)聽,在adapter的onBindViewHolder中:

holder.ivSort.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (MotionEventCompat.getActionMasked(event) ==
                        MotionEvent.ACTION_DOWN) {
                    mDragStartListener.onStartDrag(holder);
                }
                return false;
            }
        });

這里要在adapter中添加設置回調的方法:

    public void setOnDragStartListener(OnStartDragListener mDragStartListener){
        this.mDragStartListener = mDragStartListener;
    }

最后ItemTouchHelper在和RecyclerView綁定后設置監(jiān)聽:

       adapter.setOnDragStartListener(new OnStartDragListener() {
            @Override
            public void onStartDrag(RecyclerView.ViewHolder viewHolder) {
                itemTouchHelp.startDrag(viewHolder);
            }
        });

可以看到關鍵的就一句itemTouchHelp.startDrag(viewHolder)瞒大,這一句話控制某個item處于拖拽狀態(tài)螃征。

3.2 有區(qū)分的進行拖拽

有時候有些item是不可以拖拽的,我們首先在isLongPressDragEnabled中也要返回false透敌。然后在item的長按中進行區(qū)分:

@Override
 public void onItemLongClick(RecyclerView.ViewHolder vh) {
     if (ViewHolder符合拖拽條件時) {
         itemTouchHelp.startDrag(vh);
     }
 }
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末盯滚,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子酗电,更是在濱河造成了極大的恐慌魄藕,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撵术,死亡現(xiàn)場離奇詭異背率,居然都是意外死亡,警方通過查閱死者的電腦和手機嫩与,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門寝姿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人划滋,你說我怎么就攤上這事饵筑。” “怎么了处坪?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵根资,是天一觀的道長。 經(jīng)常有香客問我同窘,道長玄帕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任想邦,我火速辦了婚禮桨仿,結果婚禮上,老公的妹妹穿的比我還像新娘案狠。我一直安慰自己服傍,他們只是感情好,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布骂铁。 她就那樣靜靜地躺著吹零,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拉庵。 梳的紋絲不亂的頭發(fā)上灿椅,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音钞支,去河邊找鬼茫蛹。 笑死,一個胖子當著我的面吹牛烁挟,可吹牛的內容都是我干的婴洼。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼撼嗓,長吁一口氣:“原來是場噩夢啊……” “哼柬采!你這毒婦竟也來了?” 一聲冷哼從身側響起且警,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤粉捻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后斑芜,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肩刃,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年杏头,在試婚紗的時候發(fā)現(xiàn)自己被綠了盈包。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡大州,死狀恐怖续语,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情厦画,我是刑警寧澤疮茄,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站根暑,受9級特大地震影響力试,放射性物質發(fā)生泄漏。R本人自食惡果不足惜排嫌,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一畸裳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧淳地,春花似錦怖糊、人聲如沸帅容。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽并徘。三九已至,卻和暖如春扰魂,著一層夾襖步出監(jiān)牢的瞬間麦乞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工劝评, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留姐直,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓蒋畜,卻偏偏與公主長得像声畏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子百侧,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內容