kopia lustrzana https://github.com/ryukoposting/Signal-Android
Improve management of bubble animator listener lifecycle.
rodzic
deca8e3feb
commit
113bcca277
|
@ -1,15 +1,8 @@
|
|||
package org.thoughtcrime.securesms.conversation
|
||||
|
||||
import android.animation.LayoutTransition
|
||||
import android.animation.ValueAnimator
|
||||
import androidx.core.animation.addListener
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import java.lang.IllegalStateException
|
||||
|
||||
class BodyBubbleLayoutTransition(bodyBubble: ConversationItemBodyBubble) : LayoutTransition() {
|
||||
|
||||
private val animator: ValueAnimator = ValueAnimator.ofFloat(0f, 1f)
|
||||
|
||||
class BodyBubbleLayoutTransition : LayoutTransition() {
|
||||
init {
|
||||
disableTransitionType(APPEARING)
|
||||
disableTransitionType(DISAPPEARING)
|
||||
|
@ -17,25 +10,5 @@ class BodyBubbleLayoutTransition(bodyBubble: ConversationItemBodyBubble) : Layou
|
|||
disableTransitionType(CHANGING)
|
||||
|
||||
setDuration(100L)
|
||||
|
||||
animator.duration = getAnimator(CHANGE_DISAPPEARING).duration
|
||||
animator.addUpdateListener {
|
||||
val parentRecycler: RecyclerView? = bodyBubble.parent?.parent as? RecyclerView
|
||||
|
||||
try {
|
||||
parentRecycler?.invalidate()
|
||||
} catch (e: IllegalStateException) {
|
||||
// In scroll or layout. Skip this frame.
|
||||
}
|
||||
}
|
||||
|
||||
getAnimator(CHANGE_DISAPPEARING).addListener(
|
||||
onStart = {
|
||||
animator.start()
|
||||
},
|
||||
onEnd = {
|
||||
animator.end()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
package org.thoughtcrime.securesms.conversation;
|
||||
|
||||
import android.Manifest;
|
||||
import android.animation.Animator;
|
||||
import android.animation.LayoutTransition;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
|
@ -215,6 +218,8 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
|||
private View toolbarShadow;
|
||||
private Stopwatch startupStopwatch;
|
||||
private View reactionsShade;
|
||||
private LayoutTransition layoutTransition;
|
||||
private TransitionListener transitionListener;
|
||||
|
||||
private GiphyMp4ProjectionRecycler giphyMp4ProjectionRecycler;
|
||||
private Colorizer colorizer;
|
||||
|
@ -248,6 +253,9 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
|||
list = view.findViewById(android.R.id.list);
|
||||
composeDivider = view.findViewById(R.id.compose_divider);
|
||||
|
||||
layoutTransition = new LayoutTransition();
|
||||
transitionListener = new TransitionListener(list);
|
||||
|
||||
scrollToBottomButton = view.findViewById(R.id.scroll_to_bottom);
|
||||
scrollToMentionButton = view.findViewById(R.id.scroll_to_mention);
|
||||
scrollDateHeader = view.findViewById(R.id.scroll_date_header);
|
||||
|
@ -412,6 +420,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
|||
super.onStart();
|
||||
initializeTypingObserver();
|
||||
SignalProxyUtil.startListeningToWebsocket();
|
||||
layoutTransition.getAnimator(LayoutTransition.CHANGE_DISAPPEARING).addListener(transitionListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -435,6 +444,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
|||
public void onStop() {
|
||||
super.onStop();
|
||||
ApplicationDependencies.getTypingStatusRepository().getTypists(threadId).removeObservers(getViewLifecycleOwner());
|
||||
layoutTransition.getAnimator(LayoutTransition.CHANGE_DISAPPEARING).removeListener(transitionListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1905,4 +1915,34 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class TransitionListener implements Animator.AnimatorListener {
|
||||
|
||||
private final ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
|
||||
|
||||
TransitionListener(RecyclerView recyclerView) {
|
||||
animator.addUpdateListener(unused -> recyclerView.invalidate());
|
||||
animator.setDuration(100L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
animator.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
animator.end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
// Do Nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animator animation) {
|
||||
// Do Nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,17 +33,17 @@ public class ConversationItemBodyBubble extends LinearLayout {
|
|||
|
||||
public ConversationItemBodyBubble(Context context) {
|
||||
super(context);
|
||||
setLayoutTransition(new BodyBubbleLayoutTransition(this));
|
||||
setLayoutTransition(new BodyBubbleLayoutTransition());
|
||||
}
|
||||
|
||||
public ConversationItemBodyBubble(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setLayoutTransition(new BodyBubbleLayoutTransition(this));
|
||||
setLayoutTransition(new BodyBubbleLayoutTransition());
|
||||
}
|
||||
|
||||
public ConversationItemBodyBubble(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
setLayoutTransition(new BodyBubbleLayoutTransition(this));
|
||||
setLayoutTransition(new BodyBubbleLayoutTransition());
|
||||
}
|
||||
|
||||
public void setOutliners(@NonNull List<Outliner> outliners) {
|
||||
|
|
|
@ -358,7 +358,7 @@ public final class ConversationListItem extends ConstraintLayout
|
|||
}
|
||||
|
||||
private void observeDisplayBody(@Nullable LiveData<SpannableString> displayBody) {
|
||||
if (displayBody == null) {
|
||||
if (displayBody == null && glideRequests != null) {
|
||||
glideRequests.clear(thumbTarget);
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue