RecyclerView之ItemTouchHelp

前幾天搗鼓了一下分割線,今天來看看RecyclerView的交互吧,RecyclerView的交互離不開ItemTouchHelp這個類直接進入正題

首先導入依賴庫

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:design:25.0.0'
    compile 'com.android.support:recyclerview-v7:25.0.0'
    compile 'com.android.support:appcompat-v7:25.0.0'
}

在MainActivity中完成RecyclerView的設置和數據的初始化

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getData();
        recyclerView = findViewById(R.id.rv);
        recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
        adapter = new RecyclerViewAdapter(datas,this);
        recyclerView.setAdapter(adapter);
        //條目幫助類
        itemTouchHelper = new ItemTouchHelper(new MyItemTouchHelpCallBack(this));
        itemTouchHelper.attachToRecyclerView(recyclerView);

    }

    private void getData() {
        datas = new ArrayList<>();
        for(int i=0;i<20;i++) {
            datas.add("lkadsjfasdfsadfsa   " + i);
        }
    }

這里我們自定義一個MyItemTouchHelpCallBack 繼承 CallBack并實現它的方法

//callback回調監聽時先調用這個方法,判斷當前是什么動作,例如判斷當前動作的方向
    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        //方向有up down left right
        int up = ItemTouchHelper.UP;//0x0001
        int down = ItemTouchHelper.DOWN;//0x0010
        int left = ItemTouchHelper.LEFT;//0x0100
        int right = ItemTouchHelper.RIGHT;//0x1000
        //如果只判斷上下方向就應該返回0x0011   up|down
        //同理只判斷左右方向就應該返回0x1100   left|right
        //那系統怎么判斷呢?比如用0x0011 & 0x0001 = 0x0001  0x0011 & 0x0010 = 0x0010 這樣就判斷出上下方向了
        //源碼這里也提供了方法很方便,上面解釋方便理解

        //監聽上下方向的拖拽
        int dragFlags = up | down;
        //監聽左右方向的滑動
        int swipeFlags = left | right;
        int flags = makeMovementFlags(dragFlags, swipeFlags);
        return flags;
    }

    //拖拽移動
    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder srcHold, RecyclerView.ViewHolder targetHold) {
        //在此方法中不停調用adapter.notifyItemChanged方法刷新recyclerview中的數據
        if (srcHold.getItemViewType() != targetHold.getItemViewType()) {
            return false;
        }
        itemMoveListener.onItemMove(srcHold.getAdapterPosition(),targetHold.getAdapterPosition());
        return false;
    }
    //側滑 滑動
    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        //監聽側滑1.調用adapter.notifyRemove
        itemMoveListener.onItemRemove(viewHolder.getAdapterPosition());
    }

效果如下圖

拖拽和滑動刪除.gif

圖中有一些動畫效果不透明,同樣可以做一些其他的效果,例如拖拽的時候突出那一項等等可以在onSelectedChanged、clearView、onChildDraw中實現

 //選中某一項的時候可以做背景等處理
    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
            //半透明
            viewHolder.itemView.setAlpha(0.6f);
        }
        super.onSelectedChanged(viewHolder, actionState);

    }
    //將那一項的背景等清除
    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        //恢復背景
        viewHolder.itemView.setAlpha(1f);
        super.clearView(recyclerView, viewHolder);
    }

    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        //dX 水平方向移動  往左為負  往右為正
        if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
            //透明度動畫
            viewHolder.itemView.setAlpha(1-Math.abs(dX)/viewHolder.itemView.getWidth());
        }else{
            if (actionState != ItemTouchHelper.ACTION_STATE_DRAG)
            viewHolder.itemView.setAlpha(1f);
        }
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);

    }

好了,到這里就結束了,看源碼真的能發現不少東西,還能做好多交互的方式。明白了嗎?知道了這些原理類似與QQ的側滑刪除應該有思路了吧

項目鏈接 https://github.com/389987790/TouchedRecyclerView

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,113評論 25 708
  • 內容抽屜菜單ListViewWebViewSwitchButton按鈕點贊按鈕進度條TabLayout圖標下拉刷新...
    皇小弟閱讀 46,877評論 22 665
  • 題目叫論說話,其實本身我是一個不太會“說話”的人,跟別人溝通的時候老在講自己的問題,有時候我費盡心思說了一大堆,別...
    0233ea984dea閱讀 354評論 0 0
  • 作者:黃有璨,三節課發起人。 特別提醒:本文為萬字深度長文,無閱讀門檻,尤其適合正在運營/創業路上迷茫的朋友。完整...
    三節課閱讀 3,909評論 5 83
  • 很不幸,我的一個好友,父親得了癌癥,作為一個和醫學有點邊的人,聽到他說的癥狀時我就意識到,沒多久了。但是,這仿佛是...
    徐巖靖閱讀 316評論 0 0