最近有個需求,要實現列表的itemView拖拽後,交換位置。網上搜索了一番,發現RecyclerView來實現此方案很容易,RecyclerView的默認幾個api很強大,只需幾行代碼就能夠實現簡單的拖拽需求。api
有一篇文章值得推薦給你們,RecyclerView 擴展(二) - 手把手教你認識ItemTouchHelper; http://www.javashuo.com/article/p-cwzpfjqy-ho.html ItemTouchHelper(二)源碼簡析 https://www.jianshu.com/p/b8e45aa3a6ffide
chooseDropTarget
方法來找到符合交換條件的ItemView
。這裏符合的條件是指,選中的ItemView
的bottom
大於目標ItemView
的bottom
或者ItemView
的top
大於目標ItemView
的top
。一般來講,咱們能夠重寫chooseDropTarget
方法,來定義什麼條件下就交換位置。這裏呢,直接說重點,個人需求是要本身來控制知足必定的條件,才能交換位置。post
其實chooseDropTarget的默認實現已經知足了,他的規則是選中的ItemView的bottom大於目標itemView的bottom或者是top大於目標itemView的top值。spa
那麼我這裏想要實現的是,選中的selectedView的左右或者上下邊界,接近targetView的邊界,他們相減,有一個固定的差值,這裏我定義爲ScreenWidth() / 列數 / 單個itemView四等分code
好比: int offsetWidth = ScreenWidth / 3/ 4;blog
下面直接看代碼,能夠比較下跟chooseDropTarget的默認實現的差別,其實差很少,就是加了個固定的差值。這樣不須要拖拽到view的邊界才發生交換get
@Override public RecyclerView.ViewHolder chooseDropTarget(RecyclerView.ViewHolder selected, List<RecyclerView.ViewHolder> dropTargets, int curX, int curY) { // return super.chooseDropTarget(selected, dropTargets, curX, curY); int right = curX + selected.itemView.getWidth(); int bottom = curY + selected.itemView.getHeight(); RecyclerView.ViewHolder winner = null; int winnerScore = -1; final int dx = curX - selected.itemView.getLeft(); final int dy = curY - selected.itemView.getTop(); final int targetsSize = dropTargets.size(); for (int i = 0; i < targetsSize; i++) { final RecyclerView.ViewHolder target = dropTargets.get(i); int offsetWidth = (int) (DisplayUtils.getWindowWidth(selected.itemView.getContext()) / 12.0f); int offsetHeight = offsetWidth; if (dx > 0) { int diff = target.itemView.getRight() - offsetWidth - right; if (diff < 0 && target.itemView.getRight() > selected.itemView.getRight()) { final int score = Math.abs(diff); if (score > winnerScore) { winnerScore = score; winner = target; } } } if (dx < 0) { int diff = target.itemView.getLeft() + offsetWidth - curX; if (diff > 0 && target.itemView.getLeft() < selected.itemView.getLeft()) { final int score = Math.abs(diff); if (score > winnerScore) { winnerScore = score; winner = target; } } } if (dy < 0) { int diff = target.itemView.getTop() + offsetHeight - curY; if (diff > 0 && target.itemView.getTop() < selected.itemView.getTop()) { final int score = Math.abs(diff); if (score > winnerScore) { winnerScore = score; winner = target; } } } if (dy > 0) { int diff = target.itemView.getBottom() - offsetHeight - bottom; if (diff < 0 && target.itemView.getBottom() > selected.itemView.getBottom()) { final int score = Math.abs(diff); if (score > winnerScore) { winnerScore = score; winner = target; } } } } return winner; }