Android側(cè)滑-RecyclerView實(shí)現(xiàn)簡單高效的側(cè)滑菜單

一 前言

側(cè)滑對(duì)于Android來說實(shí)現(xiàn)方式多種多樣,但是具體那種方式能滿足我們的需求和適用場(chǎng)景那就很難說了,曾試過繼承RecyclerView,自定義Adapter等方法,但是效果并不是很理想.最終定制版的WItemTouchHelperPlus符合了大部分的側(cè)滑需求,它來自系統(tǒng)類的改造.下面來看下實(shí)現(xiàn)的效果.

仿qq的側(cè)滑,跟隨滑動(dòng)...

image

簡單的側(cè)滑點(diǎn)擊刪除,覆蓋滑動(dòng)...

image

二 知識(shí)準(zhǔn)備

ItemTouchHelper是Android系統(tǒng)提供的一個(gè)幫助類,可以很輕松的用它實(shí)現(xiàn)長按拖拽和側(cè)滑刪除功能(這里的是側(cè)滑之后直接刪除整條Item),下面來看一下使用方法.

  • ItemTouchHelper.Callback

官方的解釋是這樣的,這個(gè)類是ItemTouchHelper和您的應(yīng)用程序之間的契約。它允許您控制每個(gè)ViewHolder都啟用了哪些觸摸行為,并且在user執(zhí)行這些操作時(shí)也會(huì)接收回調(diào) .通俗來說就是我們可以再這個(gè)類里面去控制我們想要的觸摸效果,也就是側(cè)滑還是拖拽.然后可以得到動(dòng)作執(zhí)行中的回調(diào),和動(dòng)作執(zhí)行結(jié)束后的回調(diào).

我們需要繼承ItemTouchHelper.Callback來實(shí)現(xiàn)自己的邏輯.我先大致的介紹一下具體的使用方法,詳情還請(qǐng)自行查資料.請(qǐng)看代碼:

/**
 * 實(shí)現(xiàn)自己的邏輯
 * Created by WANG on 18/3/14.
 */

public class ItemTouchHelperCallback extends ItemTouchHelper.Callback {
    //是否支持側(cè)滑
    @Override
    public boolean isItemViewSwipeEnabled() {
        return true;
    }
    
    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        return makeMovementFlags(0, ItemTouchHelper.START);
    }
    
    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        return false;
    }

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

    }

    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        return;
    }

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

    }
}

//這里給RecyclerView設(shè)置一下就OK拉
ItemTouchHelperCallback touchHelperCallback = new ItemTouchHelperCallback();
ItemTouchHelper itemTouchHelper=newItemTouchHelper(touchHelperCallback);
itemTouchHelper.attachToRecyclerView(recyclerView);

下面是我目前發(fā)現(xiàn)的系統(tǒng)的ItemTouchHelper的一些弊端和好處:

弊端:

  • 當(dāng)處于滑動(dòng)狀態(tài)的時(shí)候不下發(fā)點(diǎn)擊事件.
  • 滑動(dòng)的距離為RecyclerView的寬度,往往就是屏幕的寬度.
  • 限制滑動(dòng)距離之后,無法正常恢復(fù)側(cè)滑(讓滑動(dòng)的View復(fù)位).
  • 當(dāng)Item手動(dòng)滑動(dòng)之后不能自由的自動(dòng)的恢復(fù)側(cè)滑(讓滑動(dòng)的View復(fù)位).
  • 無法做到特定的Item不讓側(cè)滑.
  • 總問言之側(cè)滑不流暢.

好處:

  • 側(cè)滑布局的樣式我們可以隨意的更改.
  • 滑動(dòng)的距離可以隨意的固定.
  • 側(cè)滑恢復(fù)的動(dòng)畫我們可以控制.
  • 總而言之給了開發(fā)者很大的自由.

三 改進(jìn)版的WItemTouchHelperPlus

  • 新增了一個(gè)接口Extension用來獲取我們側(cè)滑的距離,需要在獲取側(cè)滑控件的地方去實(shí)現(xiàn)該接口,因?yàn)樵買temTouchHelper里面我們操作的是ViewHolder,所以我們的ViewHiolder是實(shí)現(xiàn)它的最好選擇了代碼如下:
//接口
public interface Extension {

    float getActionWidth();
}
**********************Viewholder***********************
    /**
     * view.getWidth()獲取的是屏幕中可以看到的大小.
     */
    public  class RecViewholder extends RecyclerView.ViewHolder implements Extension {
        public TextView textView;
        public TextView slide;
        public RecViewholder(View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.item_text);
            slide = itemView.findViewById(R.id.item_slide);
        }
        @Override
        public float getActionWidth() {
            return  slide.getWidth();
        }

    }
  • 新增了tag.需要在我們滑動(dòng)的xml布局里面設(shè)置一個(gè)tag="slide_flag",用來標(biāo)識(shí)該布局為側(cè)滑滑動(dòng)的布局用例:
//這個(gè)標(biāo)識(shí)的布局就是我們能滑動(dòng)的布局.
<TextView
        android:id="@+id/item_text"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#e1e1e1"
        android:gravity="center"
        android:tag="slide_flag"
        android:text="item"
        android:textColor="#333333"
        android:textSize="16sp" />
  • WItemTouchHelperPlus.Callback需要重寫getItemSlideType方法返我們側(cè)滑的布局類型,就是文章開始處的跟隨GIF和覆蓋GIF兩種側(cè)滑布局.
    @Override
    public String getItemSlideType() {
        return type;
    }
  • 再onChildDraw里面做一些處理.
 @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        if (viewHolder instanceof RecAdapter.RecViewholder) {
            RecAdapter.RecViewholder holder = (RecAdapter.RecViewholder) viewHolder;
            float actionWidth = holder.getActionWidth();
            if (dX < -actionWidth) {
                dX = -actionWidth;
            }
            holder.slideItem.setTranslationX(dX);
        }else if(viewHolder instanceof RecOtherTypeAdapter.RecViewholder){
            RecOtherTypeAdapter.RecViewholder holder = (RecOtherTypeAdapter.RecViewholder) viewHolder;
            float actionWidth = holder.getActionWidth();
            if (dX < -actionWidth) {
                dX = -actionWidth;
            }
            holder.textView.setTranslationX(dX);
        }
        return;
    }

然后就是使用我們改進(jìn)版的WItemTouchHelperPlus.Callback和WItemTouchHelperPlus來實(shí)現(xiàn)側(cè)滑.基本使用和系統(tǒng)類別無差異.源碼相當(dāng)多,這里就不再貼出具體可以去Github歡迎start

結(jié)束

這里只是大概的介紹了一下定制版WItemTouchHelperPlus和系統(tǒng)類的一些不同,以及定制版的一些用法,希望大家多多指導(dǎo)文章中出現(xiàn)的錯(cuò)誤,歡迎大家的反饋,歡迎評(píng)論吐槽哦~

如果大家需要WItemTouchHelperPlus或者系統(tǒng)類ItemTouchHelper的源碼解釋的話請(qǐng)?jiān)u論區(qū)留言哦~ 謝謝各位看官!
歡迎大家關(guān)注
我的掘金
我的CSDN
我的簡書
Github

Demo地址,歡迎start

為了能夠及時(shí)解決使用者的問題,特地建了一個(gè)Android技術(shù)交流群,遇到問題或者需求可以扔到群里,群里大神妹紙多的是~

先加入QQ群 684891631 再轉(zhuǎn)微信群~

最后編輯于
?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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