2015-08-08 13 views
25

Nun, ich habe einen RecyclerView mit einem Adapter und alles funktioniert super. Die Elemente im ArrayList-Dataset werden regelmäßig aktualisiert. So ändern sich die Elemente und ihre Elemente sowie ihre Position in der Liste. Dies wird durch einfaches Sortieren erreicht und manuell diese Methoden aufrufen, wann immer Dinge passieren:Override-Animation für notifyItemChanged in RecyclerView.Adapter

// 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); 

Letztere von denen, die Ursache meines Elends ist. Jedes Mal, wenn ein Gegenstand aktualisiert wird, wird eine kleine "Blink" -Animation ausgelöst.

fand ich ein paar Lösungen:

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

// or 

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

Aber diese beiden töten die Animationen, wenn Elemente bewegen (getauscht werden). Ich möchte nur die eine Animation außer Kraft setzen und all das magisch halten. Gibt es eine Möglichkeit, dies zu tun? Und wenn es ItemAnimator außer Kraft setzt, hat jemand ein einfaches Beispiel?

Vielen Dank im Voraus!

+0

Haben Sie eine Lösung dafür gefunden? Ich habe versucht mit .setSupportsChangeAnimation (false), aber ich bekomme immer noch einen blink mit notifyItemChanged. –

Antwort

19

Ja, tat ich.

Zuerst erhalten Sie den Quellcode von DefaultItemAnimator. Nimm den Code und erstelle eine Klasse namens MyItemAnimator in deinem Projekt. Dann den ItemAnimator auf eine neue Instanz des modifizierten MyItemAnimator, etwa so:

recyclerView.setItemAnimator(new MyItemAnimator()); 

Nun geht in der neuen Klassen-Quellcode und suchen Sie die Methode

animateChangeImpl(final ChangeInfo changeInfo) { ... } 

Wir müssen einfach lokalisieren die Methode ruft wechselnde Alpha-Werte auf. Finden Sie die folgenden zwei Zeilen und entfernen Sie die alpha (0) und & agr; (1)

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

wie so

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

Hacky aber Spot auf. Link zu Unterstützung lib v7 Quelle https://android.googlesource.com/platform/frameworks/support/+/refs/heads/master/v7/recyclerview/src/android/support/v7/widget/DefaultItemAnimator.java –

+1

dies entfernt die FadeIn/Out-Effekte, wenn Sie Elemente im RecyclerView-Objekt anzeigen/ausblenden. – SolidSnake

3

Leichte Abweichungen auf Alex 'Antwort.

Anstatt die Alpha-Änderung vollständig zu entfernen, habe ich sie nur reduziert. die einzigen Veränderungen notwendig waren:

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

und

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

In beiden Fällen wird die Änderung 0-0,5 Dadurch wird die Wirkung der Entfernung das Flackern mit der Alpha geht vollständig auf 0 zugeordnet, sondern hält Die Morphing-Eigenschaften des Elements ändern die Animation.

51

Es ist ein spezielles Verfahren nur Artikel deaktivieren geändert Animationen:

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

Official docs.

+0

Ich wollte die integrierte "Dim" -Animation beim Aufruf von notifyItemChanged() entfernen - das funktionierte perfekt. Unter Verwendung von AppCompat-v7: 25.3.1 –

+0

funktioniert dies nicht gut mit constraintLayout, das in einem Element definiert ist. Einige der Gegenstände bewegen sich leicht in verschiedene Positionen und werden dann wieder normal angezeigt. funktioniert immer noch nicht wie erwartet – SolidSnake

0

In meinem Fall nahm die Recycleransicht den gesamten Platz unter der Symbolleiste ein. Alles, was ich getan habe, war das Ändern der Layout-Höhe von recycleview von wrap_content zu match_parent und das Blinken verschwand.

0

Wenn Sie nur die Daten von Recyclerview ändern, bedeutet das kein Hinzufügen oder Löschen von Elementen, dann sollten Sie diese Zeile hinzufügen.

mRecyclerview.setHasFixedSize(true); 

Damit recyclerview wissen bekommen es keine Änderung danach in Größe, die Sie anwenden können

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

Damit Animation verschwinden werden und Code wird wie Charme arbeiten :)

2

versuchen Sie,:

mRecyclerview.setItemAnimator(null); 
1

Kotlin ver sion of @Pablo A. Martínez antwort:

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

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

Verwandte Themen