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
|
package org.thoughtcrime.securesms.conversation
|
||||||
|
|
||||||
import android.animation.LayoutTransition
|
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 {
|
init {
|
||||||
disableTransitionType(APPEARING)
|
disableTransitionType(APPEARING)
|
||||||
disableTransitionType(DISAPPEARING)
|
disableTransitionType(DISAPPEARING)
|
||||||
|
@ -17,25 +10,5 @@ class BodyBubbleLayoutTransition(bodyBubble: ConversationItemBodyBubble) : Layou
|
||||||
disableTransitionType(CHANGING)
|
disableTransitionType(CHANGING)
|
||||||
|
|
||||||
setDuration(100L)
|
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;
|
package org.thoughtcrime.securesms.conversation;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.LayoutTransition;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
@ -215,6 +218,8 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||||
private View toolbarShadow;
|
private View toolbarShadow;
|
||||||
private Stopwatch startupStopwatch;
|
private Stopwatch startupStopwatch;
|
||||||
private View reactionsShade;
|
private View reactionsShade;
|
||||||
|
private LayoutTransition layoutTransition;
|
||||||
|
private TransitionListener transitionListener;
|
||||||
|
|
||||||
private GiphyMp4ProjectionRecycler giphyMp4ProjectionRecycler;
|
private GiphyMp4ProjectionRecycler giphyMp4ProjectionRecycler;
|
||||||
private Colorizer colorizer;
|
private Colorizer colorizer;
|
||||||
|
@ -248,6 +253,9 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||||
list = view.findViewById(android.R.id.list);
|
list = view.findViewById(android.R.id.list);
|
||||||
composeDivider = view.findViewById(R.id.compose_divider);
|
composeDivider = view.findViewById(R.id.compose_divider);
|
||||||
|
|
||||||
|
layoutTransition = new LayoutTransition();
|
||||||
|
transitionListener = new TransitionListener(list);
|
||||||
|
|
||||||
scrollToBottomButton = view.findViewById(R.id.scroll_to_bottom);
|
scrollToBottomButton = view.findViewById(R.id.scroll_to_bottom);
|
||||||
scrollToMentionButton = view.findViewById(R.id.scroll_to_mention);
|
scrollToMentionButton = view.findViewById(R.id.scroll_to_mention);
|
||||||
scrollDateHeader = view.findViewById(R.id.scroll_date_header);
|
scrollDateHeader = view.findViewById(R.id.scroll_date_header);
|
||||||
|
@ -412,6 +420,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||||
super.onStart();
|
super.onStart();
|
||||||
initializeTypingObserver();
|
initializeTypingObserver();
|
||||||
SignalProxyUtil.startListeningToWebsocket();
|
SignalProxyUtil.startListeningToWebsocket();
|
||||||
|
layoutTransition.getAnimator(LayoutTransition.CHANGE_DISAPPEARING).addListener(transitionListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -435,6 +444,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||||
public void onStop() {
|
public void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
ApplicationDependencies.getTypingStatusRepository().getTypists(threadId).removeObservers(getViewLifecycleOwner());
|
ApplicationDependencies.getTypingStatusRepository().getTypists(threadId).removeObservers(getViewLifecycleOwner());
|
||||||
|
layoutTransition.getAnimator(LayoutTransition.CHANGE_DISAPPEARING).removeListener(transitionListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) {
|
public ConversationItemBodyBubble(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
setLayoutTransition(new BodyBubbleLayoutTransition(this));
|
setLayoutTransition(new BodyBubbleLayoutTransition());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConversationItemBodyBubble(Context context, @Nullable AttributeSet attrs) {
|
public ConversationItemBodyBubble(Context context, @Nullable AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
setLayoutTransition(new BodyBubbleLayoutTransition(this));
|
setLayoutTransition(new BodyBubbleLayoutTransition());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConversationItemBodyBubble(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
public ConversationItemBodyBubble(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||||
super(context, attrs, defStyleAttr);
|
super(context, attrs, defStyleAttr);
|
||||||
setLayoutTransition(new BodyBubbleLayoutTransition(this));
|
setLayoutTransition(new BodyBubbleLayoutTransition());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOutliners(@NonNull List<Outliner> outliners) {
|
public void setOutliners(@NonNull List<Outliner> outliners) {
|
||||||
|
|
|
@ -358,7 +358,7 @@ public final class ConversationListItem extends ConstraintLayout
|
||||||
}
|
}
|
||||||
|
|
||||||
private void observeDisplayBody(@Nullable LiveData<SpannableString> displayBody) {
|
private void observeDisplayBody(@Nullable LiveData<SpannableString> displayBody) {
|
||||||
if (displayBody == null) {
|
if (displayBody == null && glideRequests != null) {
|
||||||
glideRequests.clear(thumbTarget);
|
glideRequests.clear(thumbTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue