Prevent change animation from firing on thread updates.

This commit is contained in:
Cody Henthorne
2026-03-05 11:48:14 -05:00
committed by jeffrey-signal
parent 5b543c5212
commit 49d3f7652d

View File

@@ -3,10 +3,14 @@ package org.thoughtcrime.securesms.conversationlist;
import android.os.Handler; import android.os.Handler;
import androidx.annotation.MainThread; import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DefaultItemAnimator; import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.RecyclerView;
import org.signal.core.util.logging.Log; import org.signal.core.util.logging.Log;
import java.util.List;
public class ConversationListItemAnimator extends DefaultItemAnimator { public class ConversationListItemAnimator extends DefaultItemAnimator {
private static final String TAG = Log.tag(ConversationListItemAnimator.class); private static final String TAG = Log.tag(ConversationListItemAnimator.class);
@@ -14,6 +18,7 @@ public class ConversationListItemAnimator extends DefaultItemAnimator {
private static final long ANIMATION_DURATION = 200; private static final long ANIMATION_DURATION = 200;
private boolean shouldDisable; private boolean shouldDisable;
private int pendingChangeMoves;
public ConversationListItemAnimator() { public ConversationListItemAnimator() {
setMoveDuration(0); setMoveDuration(0);
@@ -21,6 +26,35 @@ public class ConversationListItemAnimator extends DefaultItemAnimator {
setChangeDuration(ANIMATION_DURATION); setChangeDuration(ANIMATION_DURATION);
} }
@Override
public boolean animateChange(@NonNull RecyclerView.ViewHolder oldHolder, @NonNull RecyclerView.ViewHolder newHolder, int fromX, int fromY, int toX, int toY) {
if (fromX != toX || fromY != toY) {
pendingChangeMoves++;
return animateMove(newHolder, fromX, fromY, toX, toY);
}
dispatchChangeFinished(newHolder, true);
return false;
}
@Override
public void runPendingAnimations() {
if (pendingChangeMoves > 0) {
pendingChangeMoves = 0;
long previousMoveDuration = getMoveDuration();
setMoveDuration(getChangeDuration());
super.runPendingAnimations();
setMoveDuration(previousMoveDuration);
} else {
super.runPendingAnimations();
}
}
@Override
public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull List<Object> payloads) {
return true;
}
@MainThread @MainThread
public void enable() { public void enable() {
setMoveDuration(ANIMATION_DURATION); setMoveDuration(ANIMATION_DURATION);
@@ -42,7 +76,6 @@ public class ConversationListItemAnimator extends DefaultItemAnimator {
setChangeDuration(ANIMATION_DURATION); setChangeDuration(ANIMATION_DURATION);
} }
/** /**
* We need to reasonably ensure that the animation has started before we disable things here, so we add a slight delay. * We need to reasonably ensure that the animation has started before we disable things here, so we add a slight delay.
*/ */