2014-12-04 91 views
25

我正在構建基於RecyclerView的組件,允許用戶通過拖放來重新排序項目。 一旦我在DragListener一側,我需要它在適配器中的位置以執行正確的移動,但我只能訪問該視圖。 所以這是我做的適配器視圖結合:RecyclerView適配器notifyDataSetChanged停止花式動畫

@Override 
public void onBindViewHolder(ViewHolder viewHolder, int position) { 
    Track track = mArray.get(position); 
    viewHolder.itemView.setTag(R.string.TAG_ITEM_POSITION, position); 
} 

它看起來正確的嗎? 因爲如果我移動的項目是這樣的:

public void move(int from, int to){ 
    Track track = mArray.remove(from); 
    mArray.add(to, track); 
    notifyItemMoved(from, to); 
} 

則位置標記不再正確,如果我notifyDataSetChanged(),我失去了花哨的動畫。 有什麼建議嗎?

回答

5

不,這是錯誤的。首先,你不能引用該方法返回後傳遞給onBindViewHolder的位置。 RecyclerView在其位置改變時不會重新綁定視圖(由於物品移動等原因)。

取而代之,您可以使用ViewHolder#getPosition()這將返回您更新的位置。

如果你修好了,你的移動代碼應該可以工作&提供很好的動畫。

調用notifyDataSetChanged將阻止預測動畫,所以儘可能避免它。詳細信息請參見documentation

編輯(從評論):從外部獲取位置,從recyclerview獲取子視圖持有者,然後從vh獲取位置。見RecyclerView API的細節

+0

好的,謝謝你的回答=)但現在什麼是從adpater外部檢索位置的最佳方式(例如我的dragListener)? – elgui 2014-12-05 08:38:25

+0

從recyclerview獲取子查看持有者,然後從vh獲取位置。見RecyclerView API的細節 – yigit 2014-12-05 09:30:22

+0

偉大的,非常感謝你=) – elgui 2014-12-05 13:27:16

88

有一種方法來保護花哨的動畫只有notifyDataSetChanged()

  1. 你需要讓自己的GridLayoutManager與被覆蓋的supportsPredictiveItemAnimations()方法返回true;

  2. 您需要mAdapter.setHasStableIds(true)

  3. 我覺得棘手的是,你需要替換適配器的getItemId()方法的一部分。它應該返回真正獨特的值,而不是position的直接函數。像mItems.get(position).hashCode()

東西在我的情況下工作完全罰款 - 美麗的動畫添加,刪除和移動項目只使用notifyDataSetChanged()

+14

你爲我節省了很多痛苦的人, tyvm。順便說一句,這應該是接受答案不是上面的一個。 – 2015-04-28 23:25:17

+0

我忘了說,如果你使用DB來提供適配器,那麼第3部分的主鍵就能解決你的問題。 – 2015-04-28 23:38:19

+0

它適用於我完美!謝謝! – oriolparra 2015-07-30 08:56:04

1

1)您將使用notifyItemInserted(position);notifyItemRemoved(position);,而不是notifyDataSetChanged()動畫。 2),你只需手動解決您的問題 - 使用

public void move(int from, int to){ 
    Track track = mArray.remove(from); 
    mArray.add(to, track); 
    notifyItemMoved(from, to); 
    ViewHolder fromHolder = (ViewHolder) mRecyclerView.findViewHolderForPosition(from); 
    ViewHolder toHolder = (ViewHolder) mRecyclerView.findViewHolderForPosition(to); 
    Tag fromTag = fromHolder.itemView.getTag(); 
    fromHolder.itemView.setTag(toHolder.itemView.getTag()); 
    toHolder.itemView.setTag(fromTag); 

} 
+1

1. notifyItemChanged(位置) – worked 2015-11-01 00:54:21

0

你應該notifyItemRemoved(index)工作正常的方法移動到OnCreateViewHolder,然後。

相關問題