Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8b5c67b2 authored by Selim Cinek's avatar Selim Cinek Committed by android-build-merger
Browse files

Merge "Fixed the animations of Messaging Layout, leading to overlaps" into pi-dev am: d982210d

am: 0fc5e520

Change-Id: I601fde5804a921a9e634e342993402d4feb8031a
parents ff9f2cca 0fc5e520
Loading
Loading
Loading
Loading
+53 −55
Original line number Diff line number Diff line
@@ -100,7 +100,6 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
        super.onFinishInflate();
        mMessageContainer = findViewById(R.id.group_message_container);
        mSenderName = findViewById(R.id.message_name);
        mSenderName.addOnLayoutChangeListener(MessagingLayout.MESSAGING_PROPERTY_ANIMATOR);
        mAvatarView = findViewById(R.id.message_icon);
        mImageContainer = findViewById(R.id.messaging_group_icon_container);
        mSendingSpinner = findViewById(R.id.messaging_group_sending_progress);
@@ -190,73 +189,66 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
    }

    public void removeMessage(MessagingMessage messagingMessage) {
        ViewGroup messageParent = (ViewGroup) messagingMessage.getView().getParent();
        messageParent.removeView(messagingMessage.getView());
        View view = messagingMessage.getView();
        boolean wasShown = view.isShown();
        ViewGroup messageParent = (ViewGroup) view.getParent();
        if (messageParent == null) {
            return;
        }
        messageParent.removeView(view);
        Runnable recycleRunnable = () -> {
            messageParent.removeTransientView(messagingMessage.getView());
            messageParent.removeTransientView(view);
            messagingMessage.recycle();
            if (mMessageContainer.getChildCount() == 0
                    && mMessageContainer.getTransientViewCount() == 0
                    && mImageContainer.getChildCount() == 0) {
                ViewParent parent = getParent();
                if (parent instanceof ViewGroup) {
                    ((ViewGroup) parent).removeView(MessagingGroup.this);
        };
        if (wasShown && !MessagingLinearLayout.isGone(view)) {
            messageParent.addTransientView(view, 0);
            performRemoveAnimation(view, recycleRunnable);
        } else {
            recycleRunnable.run();
        }
    }

    public void recycle() {
        if (mIsolatedMessage != null) {
            mImageContainer.removeView(mIsolatedMessage);
        }
        for (int i = 0; i < mMessages.size(); i++) {
            MessagingMessage message = mMessages.get(i);
            mMessageContainer.removeView(message.getView());
            message.recycle();
        }
        setAvatar(null);
        mAvatarView.setAlpha(1.0f);
        mAvatarView.setTranslationY(0.0f);
        mSenderName.setAlpha(1.0f);
        mSenderName.setTranslationY(0.0f);
        setAlpha(1.0f);
        mIsolatedMessage = null;
        mMessages = null;
        mAddedMessages.clear();
        mFirstLayout = true;
        MessagingPropertyAnimator.recycle(this);
        sInstancePool.release(MessagingGroup.this);
    }
        };
        if (isShown()) {
            messageParent.addTransientView(messagingMessage.getView(), 0);
            performRemoveAnimation(messagingMessage.getView(), recycleRunnable);
            if (mMessageContainer.getChildCount() == 0
                    && mImageContainer.getChildCount() == 0) {
                removeGroupAnimated(null);
            }
        } else {
            recycleRunnable.run();
        }

    }

    private void removeGroupAnimated(Runnable endAction) {
        performRemoveAnimation(mAvatarView, null);
        performRemoveAnimation(mSenderName, null);
        boolean endActionTriggered = false;
        for (int i = mMessageContainer.getChildCount() - 1; i >= 0; i--) {
            View child = mMessageContainer.getChildAt(i);
            if (child.getVisibility() == View.GONE) {
                continue;
            }
            final ViewGroup.LayoutParams lp = child.getLayoutParams();
            if (lp instanceof MessagingLinearLayout.LayoutParams
                    && ((MessagingLinearLayout.LayoutParams) lp).hide
                    && !((MessagingLinearLayout.LayoutParams) lp).visibleBefore) {
                continue;
            }
            Runnable childEndAction = endActionTriggered ? null : endAction;
            performRemoveAnimation(child, childEndAction);
            endActionTriggered = true;
        }
        if (mIsolatedMessage != null) {
            performRemoveAnimation(mIsolatedMessage, !endActionTriggered ? endAction : null);
            endActionTriggered = true;
        }
        if (!endActionTriggered && endAction != null) {
    public void removeGroupAnimated(Runnable endAction) {
        performRemoveAnimation(this, () -> {
            setAlpha(1.0f);
            MessagingPropertyAnimator.setToLaidOutPosition(this);
            if (endAction != null) {
                endAction.run();
            }
        });
    }

    public void performRemoveAnimation(View message, Runnable endAction) {
        MessagingPropertyAnimator.fadeOut(message, endAction);
        MessagingPropertyAnimator.startLocalTranslationTo(message,
                (int) (-getHeight() * 0.5f), MessagingLayout.FAST_OUT_LINEAR_IN);
        performRemoveAnimation(message, -message.getHeight(), endAction);
    }

    private void performRemoveAnimation(View view, int disappearTranslation, Runnable endAction) {
        MessagingPropertyAnimator.startLocalTranslationTo(view, disappearTranslation,
                MessagingLayout.FAST_OUT_LINEAR_IN);
        MessagingPropertyAnimator.fadeOut(view, endAction);
    }

    public CharSequence getSenderName() {
@@ -341,6 +333,11 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
        }
    }

    @Override
    public boolean hasOverlappingRendering() {
        return false;
    }

    public Icon getAvatarSymbolIfMatching(CharSequence avatarName, String avatarSymbol,
            int layoutColor) {
        if (mAvatarName.equals(avatarName) && mAvatarSymbol.equals(avatarSymbol)
@@ -458,6 +455,7 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (!mAddedMessages.isEmpty()) {
            final boolean firstLayout = mFirstLayout;
            getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
@@ -466,7 +464,7 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
                            continue;
                        }
                        MessagingPropertyAnimator.fadeIn(message.getView());
                        if (!mFirstLayout) {
                        if (!firstLayout) {
                            MessagingPropertyAnimator.startLocalTranslationFrom(message.getView(),
                                    message.getView().getHeight(),
                                    MessagingLayout.LINEAR_OUT_SLOW_IN);
+0 −2
Original line number Diff line number Diff line
@@ -170,8 +170,6 @@ public class MessagingImageMessage extends ImageView implements MessagingMessage

    public void recycle() {
        MessagingMessage.super.recycle();
        setAlpha(1.0f);
        setTranslationY(0);
        setImageBitmap(null);
        mDrawable = null;
        sInstancePool.release(this);
+30 −0
Original line number Diff line number Diff line
@@ -180,8 +180,13 @@ public class MessagingLayout extends FrameLayout {
        List<MessagingMessage> historicMessages = createMessages(newHistoricMessages,
                true /* isHistoric */);
        List<MessagingMessage> messages = createMessages(newMessages, false /* isHistoric */);

        ArrayList<MessagingGroup> oldGroups = new ArrayList<>(mGroups);
        addMessagesToGroups(historicMessages, messages, showSpinner);

        // Let's first check which groups were removed altogether and remove them in one animation
        removeGroups(oldGroups);

        // Let's remove the remaining messages
        mMessages.forEach(REMOVE_MESSAGE);
        mHistoricMessages.forEach(REMOVE_MESSAGE);
@@ -193,6 +198,31 @@ public class MessagingLayout extends FrameLayout {
        updateTitleAndNamesDisplay();
    }

    private void removeGroups(ArrayList<MessagingGroup> oldGroups) {
        int size = oldGroups.size();
        for (int i = 0; i < size; i++) {
            MessagingGroup group = oldGroups.get(i);
            if (!mGroups.contains(group)) {
                List<MessagingMessage> messages = group.getMessages();
                Runnable endRunnable = () -> {
                    mMessagingLinearLayout.removeTransientView(group);
                    group.recycle();
                };

                boolean wasShown = group.isShown();
                mMessagingLinearLayout.removeView(group);
                if (wasShown && !MessagingLinearLayout.isGone(group)) {
                    mMessagingLinearLayout.addTransientView(group, 0);
                    group.removeGroupAnimated(endRunnable);
                } else {
                    endRunnable.run();
                }
                mMessages.removeAll(messages);
                mHistoricMessages.removeAll(messages);
            }
        }
    }

    private void updateTitleAndNamesDisplay() {
        ArrayMap<CharSequence, String> uniqueNames = new ArrayMap<>();
        ArrayMap<Character, CharSequence> uniqueCharacters = new ArrayMap<>();
+26 −9
Original line number Diff line number Diff line
@@ -163,15 +163,6 @@ public class MessagingLinearLayout extends ViewGroup {
            }
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            MessagingChild messagingChild = (MessagingChild) child;
            if (lp.hide) {
                if (shown && lp.visibleBefore) {
                    messagingChild.hideAnimated();
                }
                lp.visibleBefore = false;
                continue;
            } else {
                lp.visibleBefore = true;
            }

            final int childWidth = child.getMeasuredWidth();
            final int childHeight = child.getMeasuredHeight();
@@ -182,6 +173,19 @@ public class MessagingLinearLayout extends ViewGroup {
            } else {
                childLeft = paddingLeft + lp.leftMargin;
            }
            if (lp.hide) {
                if (shown && lp.visibleBefore) {
                    // We still want to lay out the child to have great animations
                    child.layout(childLeft, childTop, childLeft + childWidth,
                            childTop + lp.lastVisibleHeight);
                    messagingChild.hideAnimated();
                }
                lp.visibleBefore = false;
                continue;
            } else {
                lp.visibleBefore = true;
                lp.lastVisibleHeight = childHeight;
            }

            if (!first) {
                childTop += mSpacing;
@@ -228,6 +232,18 @@ public class MessagingLinearLayout extends ViewGroup {
        return copy;
    }

    public static boolean isGone(View view) {
        if (view.getVisibility() == View.GONE) {
            return true;
        }
        final ViewGroup.LayoutParams lp = view.getLayoutParams();
        if (lp instanceof MessagingLinearLayout.LayoutParams
                && ((MessagingLinearLayout.LayoutParams) lp).hide) {
            return true;
        }
        return false;
    }

    /**
     * Sets how many lines should be displayed at most
     */
@@ -263,6 +279,7 @@ public class MessagingLinearLayout extends ViewGroup {

        public boolean hide = false;
        public boolean visibleBefore = false;
        public int lastVisibleHeight;

        public LayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);
+2 −3
Original line number Diff line number Diff line
@@ -124,8 +124,7 @@ public interface MessagingMessage extends MessagingLinearLayout.MessagingChild {
    @Override
    default void hideAnimated() {
        setIsHidingAnimated(true);
        getGroup().performRemoveAnimation(getState().getHostView(),
                () -> setIsHidingAnimated(false));
        getGroup().performRemoveAnimation(getView(), () -> setIsHidingAnimated(false));
    }

    default boolean hasOverlappingRendering() {
@@ -133,7 +132,7 @@ public interface MessagingMessage extends MessagingLinearLayout.MessagingChild {
    }

    default void recycle() {
        getState().reset();
        getState().recycle();
    }

    default View getView() {
Loading