2015-08-08 42 views
25

嗯,我有一個RecyclerView和一個適配器,一切都很好。 ArrayList數據集中的項目正在定期更新。所以項目和它們的元素以及它們在列表中的位置都會改變。這是通過簡單的排序實現並手動調用這些方法,每當事情發生了:覆蓋RecyclerView.Adapter中的notifyItemChanged動畫

// swapping two items 
Collections.swap(items, i, j); 
itemsAdapter.notifyItemMoved(i, j); 

// adding a new one 
itemAdapter.notifyItemInserted(items.size()); 

// when updating valus 
itemAdapter.notifyItemChanged(i); 

後者,是我痛苦的原因。每次更新項目時,都會觸發一個「閃爍」動畫。

我發現這幾個解決方案:

// disabling all animations 
recyclerView.getItemAnimator().setSupportsChangeAnimations(false); 

// or 

// setting the animation duration to zero, 
recyclerView.getItemAnimator().setChangeDuration(0); 

但是這兩種殺動畫項目時移動(被交換)。我只想重寫一個動畫並保留所有這些魔法。有沒有辦法做到這一點?如果它重寫ItemAnimator,有沒有人有一個簡單的例子?

在此先感謝!

+0

您是否找到了解決方案。我嘗試使用.setSupportsChangeAnimation(false),但我仍然與notifyItemChanged閃爍。 –

回答

19

是的,我做到了。

首先,獲取DefaultItemAnimator的源代碼。獲取代碼並在您的項目中創建一個名爲MyItemAnimator的類。然後,設置ItemAnimator您修改MyItemAnimator的新實例,就像這樣:

recyclerView.setItemAnimator(new MyItemAnimator()); 

現在,走在新類的源代碼,並找到方法

animateChangeImpl(final ChangeInfo changeInfo) { ... } 

我們只需要找到方法調用改變alpha值。找到以下兩行並刪除阿爾法(0)和阿爾法(1)

oldViewAnim.alpha(0).setListener(new VpaListenerAdapter() { ... } 
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).alpha(1).setListener(new VpaListenerAdapter() { ... } 

像這樣

oldViewAnim.setListener(new VpaListenerAdapter() { ... } 
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).setListener(new VpaListenerAdapter() { ... } 
+2

哈克,但現貨。鏈接到支持lib v7源碼https://android.googlesource.com/platform/frameworks/support/+/refs/heads/master/v7/recyclerview/src/android/support/v7/widget/DefaultItemAnimator.java –

+1

這可以消除當您在recyclerview項目中顯示/隱藏項目時的淡入/淡出效果。 – SolidSnake

3

在Alex的答案稍有不同。

代替完全移除所述α變化的,我只減少它。所需的唯一改變是:

 //changed alpha from 0 
     ViewCompat.setAlpha(newHolder.itemView, 0.5f); 

 //changed alpha from 0 
     oldViewAnim.alpha(0.5f).setListener(new VpaListenerAdapter() { 

在兩種情況下,改變爲0〜0.5 這具有消除與α打算完全至0相關聯的閃爍的效果,但保持該項目的變形質量改變動畫。

51

有禁用只是項目專用的方法改變了動畫:

((SimpleItemAnimator) myRecyclerView.getItemAnimator()).setSupportsChangeAnimations(false); 

Official docs

+0

我想在調用notifyItemChanged()時刪除內置的「暗淡」動畫 - 這個工作完美無缺。使用AppCompat-v7:25.3.1 –

+0

這不適用於在項目中定義的constraintLayout。一些項目稍微移動到不同的位置,然後再次正常顯示。仍然無法正常工作 – SolidSnake

0

在我的情況下,recyclerview佔據了工具欄下的所有空間。我所做的只是將recyclerview的layout_height從wrap_content更改爲match_parent,並且閃爍消失。

0

如果您只修改Recyclerview的數據意味着不添加或刪除項目,那麼您應該添加此行。

mRecyclerview.setHasFixedSize(true); 

這樣recyclerview會了解有在之後的大小沒有變化,你可以申請

((SimpleItemAnimator) mRecyclerview.getItemAnimator()).setSupportsChangeAnimations(false); 

因此該動畫將消失,代碼會像魅力:)

2

嘗試設置:

mRecyclerview.setItemAnimator(null); 
1

科特林版本sion of @Pablo A. Martínez回答:

(recyclerView.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false 
+1

(recyclerView.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false – Salmaan