11d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek/*
21d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek * Copyright (C) 2017 The Android Open Source Project
31d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek *
41d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek * Licensed under the Apache License, Version 2.0 (the "License");
51d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek * you may not use this file except in compliance with the License.
61d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek * You may obtain a copy of the License at
71d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek *
81d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek *      http://www.apache.org/licenses/LICENSE-2.0
91d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek *
101d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek * Unless required by applicable law or agreed to in writing, software
111d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek * distributed under the License is distributed on an "AS IS" BASIS,
121d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek * See the License for the specific language governing permissions and
141d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek * limitations under the License
151d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek */
161d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
171d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinekpackage com.android.systemui.statusbar.notification;
181d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
191d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinekimport android.content.res.Resources;
201d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinekimport android.util.Pools;
211d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinekimport android.view.View;
221d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinekimport android.view.ViewGroup;
231d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
241d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinekimport com.android.internal.widget.MessagingGroup;
257199ed910e2c84d17f755b2449e532af47e50a78Selim Cinekimport com.android.internal.widget.MessagingImageMessage;
261d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinekimport com.android.internal.widget.MessagingLayout;
271d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinekimport com.android.internal.widget.MessagingLinearLayout;
281d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinekimport com.android.internal.widget.MessagingMessage;
291d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinekimport com.android.internal.widget.MessagingPropertyAnimator;
301d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinekimport com.android.systemui.Interpolators;
311d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
321d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinekimport java.util.ArrayList;
331d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinekimport java.util.HashMap;
347199ed910e2c84d17f755b2449e532af47e50a78Selim Cinekimport java.util.List;
351d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
361d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek/**
371d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek * A transform state of the action list
381d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek*/
391d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinekpublic class MessagingLayoutTransformState extends TransformState {
401d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
411d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    private static Pools.SimplePool<MessagingLayoutTransformState> sInstancePool
421d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            = new Pools.SimplePool<>(40);
431d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    private MessagingLinearLayout mMessageContainer;
441d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    private MessagingLayout mMessagingLayout;
451d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    private HashMap<MessagingGroup, MessagingGroup> mGroupMap = new HashMap<>();
461d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    private float mRelativeTranslationOffset;
471d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
481d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    public static MessagingLayoutTransformState obtain() {
491d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        MessagingLayoutTransformState instance = sInstancePool.acquire();
501d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        if (instance != null) {
511d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            return instance;
521d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
531d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        return new MessagingLayoutTransformState();
541d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
551d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
561d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    @Override
571d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    public void initFrom(View view, TransformInfo transformInfo) {
581d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        super.initFrom(view, transformInfo);
591d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        if (mTransformedView instanceof MessagingLinearLayout) {
601d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            mMessageContainer = (MessagingLinearLayout) mTransformedView;
611d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            mMessagingLayout = mMessageContainer.getMessagingLayout();
621d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            Resources resources = view.getContext().getResources();
631d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            mRelativeTranslationOffset = resources.getDisplayMetrics().density * 8;
641d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
651d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
661d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
671d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    @Override
681d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    public boolean transformViewTo(TransformState otherState, float transformationAmount) {
691d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        if (otherState instanceof MessagingLayoutTransformState) {
701d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            // It's a party! Let's transform between these two layouts!
711d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            transformViewInternal((MessagingLayoutTransformState) otherState, transformationAmount,
721d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    true /* to */);
731d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            return true;
741d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        } else {
751d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            return super.transformViewTo(otherState, transformationAmount);
761d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
771d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
781d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
791d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    @Override
801d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    public void transformViewFrom(TransformState otherState, float transformationAmount) {
811d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        if (otherState instanceof MessagingLayoutTransformState) {
821d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            // It's a party! Let's transform between these two layouts!
831d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            transformViewInternal((MessagingLayoutTransformState) otherState, transformationAmount,
841d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    false /* to */);
851d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        } else {
861d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            super.transformViewFrom(otherState, transformationAmount);
871d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
881d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
891d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
901d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    private void transformViewInternal(MessagingLayoutTransformState mlt,
911d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            float transformationAmount, boolean to) {
921b38ecae862675091228b2b0440085b2d4ee6f8eSelim Cinek        ensureVisible();
931d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        ArrayList<MessagingGroup> ownGroups = filterHiddenGroups(
941d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                mMessagingLayout.getMessagingGroups());
951d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        ArrayList<MessagingGroup> otherGroups = filterHiddenGroups(
961d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                mlt.mMessagingLayout.getMessagingGroups());
971d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        HashMap<MessagingGroup, MessagingGroup> pairs = findPairs(ownGroups, otherGroups);
981d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        MessagingGroup lastPairedGroup = null;
991d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        float currentTranslation = 0;
1001d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        float transformationDistanceRemaining = 0;
1011d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        for (int i = ownGroups.size() - 1; i >= 0; i--) {
1021d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            MessagingGroup ownGroup = ownGroups.get(i);
1031d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            MessagingGroup matchingGroup = pairs.get(ownGroup);
1041d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            if (!isGone(ownGroup)) {
1051d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                if (matchingGroup != null) {
1061d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    transformGroups(ownGroup, matchingGroup, transformationAmount, to);
1071d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    if (lastPairedGroup == null) {
1081d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                        lastPairedGroup = ownGroup;
1091d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                        if (to){
1101d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                            float totalTranslation = ownGroup.getTop() - matchingGroup.getTop();
1111d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                            transformationDistanceRemaining
1121d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                                    = matchingGroup.getAvatar().getTranslationY();
1131d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                            currentTranslation = transformationDistanceRemaining - totalTranslation;
1141d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                        } else {
1151d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                            float totalTranslation = matchingGroup.getTop() - ownGroup.getTop();
1161d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                            currentTranslation = ownGroup.getAvatar().getTranslationY();
1171d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                            transformationDistanceRemaining = currentTranslation - totalTranslation;
1181d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                        }
1191d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    }
1201d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                } else {
1211d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    float groupTransformationAmount = transformationAmount;
1221d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    if (lastPairedGroup != null) {
1231d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                        adaptGroupAppear(ownGroup, transformationAmount, currentTranslation,
1241d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                                to);
1251d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                        int distance = lastPairedGroup.getTop() - ownGroup.getTop();
1261d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                        float transformationDistance = mTransformInfo.isAnimating()
1271d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                                ? distance
1281d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                                : ownGroup.getHeight() * 0.75f;
1291d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                        float translationProgress = transformationDistanceRemaining
1301d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                                - (distance - transformationDistance);
1311d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                        groupTransformationAmount =
1321d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                                translationProgress / transformationDistance;
1331d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                        groupTransformationAmount = Math.max(0.0f, Math.min(1.0f,
1341d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                                groupTransformationAmount));
1351d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                        if (to) {
1361d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                            groupTransformationAmount = 1.0f - groupTransformationAmount;
1371d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                        }
1381d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    }
1391d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    if (to) {
1401d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                        disappear(ownGroup, groupTransformationAmount);
1411d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    } else {
1421d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                        appear(ownGroup, groupTransformationAmount);
1431d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    }
1441d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                }
1451d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            }
1461d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
1471d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
1481d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
1491d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    private void appear(MessagingGroup ownGroup, float transformationAmount) {
1501d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        MessagingLinearLayout ownMessages = ownGroup.getMessageContainer();
1511d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        for (int j = 0; j < ownMessages.getChildCount(); j++) {
1521d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            View child = ownMessages.getChildAt(j);
1531d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            if (isGone(child)) {
1541d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                continue;
1551d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            }
1561d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            appear(child, transformationAmount);
1571d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            setClippingDeactivated(child, true);
1581d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
1591d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        appear(ownGroup.getAvatar(), transformationAmount);
1601397ea3b910d0981dc4bf91016a78af8fcec08bfSelim Cinek        appear(ownGroup.getSenderView(), transformationAmount);
1617199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek        appear(ownGroup.getIsolatedMessage(), transformationAmount);
1621397ea3b910d0981dc4bf91016a78af8fcec08bfSelim Cinek        setClippingDeactivated(ownGroup.getSenderView(), true);
1631d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        setClippingDeactivated(ownGroup.getAvatar(), true);
1641d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
1651d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
1661d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    private void adaptGroupAppear(MessagingGroup ownGroup, float transformationAmount,
1671d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            float overallTranslation, boolean to) {
1681d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        float relativeOffset;
1691d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        if (to) {
1701d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            relativeOffset = transformationAmount * mRelativeTranslationOffset;
1711d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        } else {
1721d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            relativeOffset = (1.0f - transformationAmount) * mRelativeTranslationOffset;
1731d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
1741397ea3b910d0981dc4bf91016a78af8fcec08bfSelim Cinek        if (ownGroup.getSenderView().getVisibility() != View.GONE) {
1751d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            relativeOffset *= 0.5f;
1761d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
1771d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        ownGroup.getMessageContainer().setTranslationY(relativeOffset);
1781d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        ownGroup.setTranslationY(overallTranslation * 0.85f);
1791d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
1801d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
1811d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    private void disappear(MessagingGroup ownGroup, float transformationAmount) {
1821d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        MessagingLinearLayout ownMessages = ownGroup.getMessageContainer();
1831d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        for (int j = 0; j < ownMessages.getChildCount(); j++) {
1841d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            View child = ownMessages.getChildAt(j);
1851d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            if (isGone(child)) {
1861d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                continue;
1871d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            }
1881d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            disappear(child, transformationAmount);
1891d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            setClippingDeactivated(child, true);
1901d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
1911d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        disappear(ownGroup.getAvatar(), transformationAmount);
1921397ea3b910d0981dc4bf91016a78af8fcec08bfSelim Cinek        disappear(ownGroup.getSenderView(), transformationAmount);
1937199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek        disappear(ownGroup.getIsolatedMessage(), transformationAmount);
1941397ea3b910d0981dc4bf91016a78af8fcec08bfSelim Cinek        setClippingDeactivated(ownGroup.getSenderView(), true);
1951d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        setClippingDeactivated(ownGroup.getAvatar(), true);
1961d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
1971d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
1981d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    private void appear(View child, float transformationAmount) {
1997199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek        if (child == null || child.getVisibility() == View.GONE) {
2001d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            return;
2011d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
2021d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        TransformState ownState = TransformState.createFrom(child, mTransformInfo);
2031d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        ownState.appear(transformationAmount, null);
2041d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        ownState.recycle();
2051d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
2061d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
2071d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    private void disappear(View child, float transformationAmount) {
2087199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek        if (child == null || child.getVisibility() == View.GONE) {
2091d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            return;
2101d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
2111d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        TransformState ownState = TransformState.createFrom(child, mTransformInfo);
2121d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        ownState.disappear(transformationAmount, null);
2131d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        ownState.recycle();
2141d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
2151d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
2161d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    private ArrayList<MessagingGroup> filterHiddenGroups(
2171d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            ArrayList<MessagingGroup> groups) {
2181d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        ArrayList<MessagingGroup> result = new ArrayList<>(groups);
2191d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        for (int i = 0; i < result.size(); i++) {
2201d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            MessagingGroup messagingGroup = result.get(i);
2211d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            if (isGone(messagingGroup)) {
2221d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                result.remove(i);
2231d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                i--;
2241d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            }
2251d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
2261d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        return result;
2271d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
2281d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
2291d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    private void transformGroups(MessagingGroup ownGroup, MessagingGroup otherGroup,
2301d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            float transformationAmount, boolean to) {
2317199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek        boolean useLinearTransformation =
2327199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek                otherGroup.getIsolatedMessage() == null && !mTransformInfo.isAnimating();
2331397ea3b910d0981dc4bf91016a78af8fcec08bfSelim Cinek        transformView(transformationAmount, to, ownGroup.getSenderView(), otherGroup.getSenderView(),
2347199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek                true /* sameAsAny */, useLinearTransformation);
2351d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        transformView(transformationAmount, to, ownGroup.getAvatar(), otherGroup.getAvatar(),
2367199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek                true /* sameAsAny */, useLinearTransformation);
2377199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek        List<MessagingMessage> ownMessages = ownGroup.getMessages();
2387199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek        List<MessagingMessage> otherMessages = otherGroup.getMessages();
2391d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        float previousTranslation = 0;
2407199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek        for (int i = 0; i < ownMessages.size(); i++) {
2417199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek            View child = ownMessages.get(ownMessages.size() - 1 - i).getView();
2421d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            if (isGone(child)) {
2431d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                continue;
2441d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            }
2457199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek            int otherIndex = otherMessages.size() - 1 - i;
2461d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            View otherChild = null;
2471d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            if (otherIndex >= 0) {
2487199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek                otherChild = otherMessages.get(otherIndex).getView();
2491d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                if (isGone(otherChild)) {
2501d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    otherChild = null;
2511d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                }
2521d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            }
2531d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            if (otherChild == null) {
2541d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                float distanceToTop = child.getTop() + child.getHeight() + previousTranslation;
2551d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                transformationAmount = distanceToTop / child.getHeight();
2561d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                transformationAmount = Math.max(0.0f, Math.min(1.0f, transformationAmount));
2571d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                if (to) {
2581d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    transformationAmount = 1.0f - transformationAmount;
2591d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                }
2601d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            }
2617199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek            transformView(transformationAmount, to, child, otherChild, false, /* sameAsAny */
2627199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek                    useLinearTransformation);
2637199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek            if (transformationAmount == 0.0f
2647199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek                    && otherGroup.getIsolatedMessage() == otherChild) {
2657199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek                ownGroup.setTransformingImages(true);
2667199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek            }
2671d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            if (otherChild == null) {
2681d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                child.setTranslationY(previousTranslation);
2691d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                setClippingDeactivated(child, true);
2701d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            } else if (to) {
2711d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                float totalTranslation = child.getTop() + ownGroup.getTop()
2721d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                        - otherChild.getTop() - otherChild.getTop();
2731d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                previousTranslation = otherChild.getTranslationY() - totalTranslation;
2741d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            } else {
2751d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                previousTranslation = child.getTranslationY();
2761d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            }
2771d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
2787199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek        ownGroup.updateClipRect();
2791d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
2801d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
2811d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    private void transformView(float transformationAmount, boolean to, View ownView,
2827199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek            View otherView, boolean sameAsAny, boolean useLinearTransformation) {
2831d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        TransformState ownState = TransformState.createFrom(ownView, mTransformInfo);
2847199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek        if (useLinearTransformation) {
2851d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            ownState.setDefaultInterpolator(Interpolators.LINEAR);
2861d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
2871d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        ownState.setIsSameAsAnyView(sameAsAny);
2881d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        if (to) {
2891d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            if (otherView != null) {
2901d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                TransformState otherState = TransformState.createFrom(otherView, mTransformInfo);
2911d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                ownState.transformViewTo(otherState, transformationAmount);
2921d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                otherState.recycle();
2931d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            } else {
2941d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                ownState.disappear(transformationAmount, null);
2951d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            }
2961d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        } else {
2971d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            if (otherView != null) {
2981d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                TransformState otherState = TransformState.createFrom(otherView, mTransformInfo);
2991d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                ownState.transformViewFrom(otherState, transformationAmount);
3001d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                otherState.recycle();
3011d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            } else {
3021d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                ownState.appear(transformationAmount, null);
3031d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            }
3041d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
3051d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        ownState.recycle();
3061d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
3071d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
3081d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    private HashMap<MessagingGroup, MessagingGroup> findPairs(ArrayList<MessagingGroup> ownGroups,
3091d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            ArrayList<MessagingGroup> otherGroups) {
3101d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        mGroupMap.clear();
3111d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        int lastMatch = Integer.MAX_VALUE;
3121d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        for (int i = ownGroups.size() - 1; i >= 0; i--) {
3131d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            MessagingGroup ownGroup = ownGroups.get(i);
3141d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            MessagingGroup bestMatch = null;
3151d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            int bestCompatibility = 0;
3161d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            for (int j = Math.min(otherGroups.size(), lastMatch) - 1; j >= 0; j--) {
3171d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                MessagingGroup otherGroup = otherGroups.get(j);
3181d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                int compatibility = ownGroup.calculateGroupCompatibility(otherGroup);
3191d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                if (compatibility > bestCompatibility) {
3201d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    bestCompatibility = compatibility;
3211d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    bestMatch = otherGroup;
3221d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    lastMatch = j;
3231d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                }
3241d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            }
3251d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            if (bestMatch != null) {
3261d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                mGroupMap.put(ownGroup, bestMatch);
3271d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            }
3281d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
3291d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        return mGroupMap;
3301d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
3311d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
3321d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    private boolean isGone(View view) {
3331d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        if (view.getVisibility() == View.GONE) {
3341d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            return true;
3351d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
3361d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        final ViewGroup.LayoutParams lp = view.getLayoutParams();
3371d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        if (lp instanceof MessagingLinearLayout.LayoutParams
3381d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                && ((MessagingLinearLayout.LayoutParams) lp).hide) {
3391d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            return true;
3401d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
3411d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        return false;
3421d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
3431d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
3441d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    @Override
3451d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    public void setVisible(boolean visible, boolean force) {
3461b38ecae862675091228b2b0440085b2d4ee6f8eSelim Cinek        super.setVisible(visible, force);
3471d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        resetTransformedView();
3481d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        ArrayList<MessagingGroup> ownGroups = mMessagingLayout.getMessagingGroups();
3491d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        for (int i = 0; i < ownGroups.size(); i++) {
3501d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            MessagingGroup ownGroup = ownGroups.get(i);
3511d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            if (!isGone(ownGroup)) {
3521d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                MessagingLinearLayout ownMessages = ownGroup.getMessageContainer();
3531d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                for (int j = 0; j < ownMessages.getChildCount(); j++) {
3547199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek                    View child = ownMessages.getChildAt(j);
3551d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    setVisible(child, visible, force);
3561d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                }
3571d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                setVisible(ownGroup.getAvatar(), visible, force);
3581397ea3b910d0981dc4bf91016a78af8fcec08bfSelim Cinek                setVisible(ownGroup.getSenderView(), visible, force);
3597199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek                MessagingImageMessage isolatedMessage = ownGroup.getIsolatedMessage();
3607199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek                if (isolatedMessage != null) {
3617199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek                    setVisible(isolatedMessage, visible, force);
3627199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek                }
3631d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            }
3641d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
3651d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
3661d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
3671d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    private void setVisible(View child, boolean visible, boolean force) {
3681d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        if (isGone(child) || MessagingPropertyAnimator.isAnimatingAlpha(child)) {
3691d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            return;
3701d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
3711d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        TransformState ownState = TransformState.createFrom(child, mTransformInfo);
3721d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        ownState.setVisible(visible, force);
3731d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        ownState.recycle();
3741d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
3751d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
3761d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    @Override
3771d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    protected void resetTransformedView() {
3781d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        super.resetTransformedView();
3791d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        ArrayList<MessagingGroup> ownGroups = mMessagingLayout.getMessagingGroups();
3801d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        for (int i = 0; i < ownGroups.size(); i++) {
3811d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            MessagingGroup ownGroup = ownGroups.get(i);
3821d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            if (!isGone(ownGroup)) {
3831d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                MessagingLinearLayout ownMessages = ownGroup.getMessageContainer();
3841d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                for (int j = 0; j < ownMessages.getChildCount(); j++) {
3851d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    View child = ownMessages.getChildAt(j);
3861d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    if (isGone(child)) {
3871d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                        continue;
3881d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    }
3891d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    resetTransformedView(child);
3901d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                    setClippingDeactivated(child, false);
3911d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                }
3921d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                resetTransformedView(ownGroup.getAvatar());
3931397ea3b910d0981dc4bf91016a78af8fcec08bfSelim Cinek                resetTransformedView(ownGroup.getSenderView());
3947199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek                MessagingImageMessage isolatedMessage = ownGroup.getIsolatedMessage();
3957199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek                if (isolatedMessage != null) {
3967199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek                    resetTransformedView(isolatedMessage);
3977199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek                }
3981d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                setClippingDeactivated(ownGroup.getAvatar(), false);
3991397ea3b910d0981dc4bf91016a78af8fcec08bfSelim Cinek                setClippingDeactivated(ownGroup.getSenderView(), false);
4001d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                ownGroup.setTranslationY(0);
4011d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek                ownGroup.getMessageContainer().setTranslationY(0);
4021d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek            }
4037199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek            ownGroup.setTransformingImages(false);
4047199ed910e2c84d17f755b2449e532af47e50a78Selim Cinek            ownGroup.updateClipRect();
4051d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        }
4061d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
4071d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
40894529dff6ca8cbb78c5f3123ebb623b6e9317156Selim Cinek    @Override
40994529dff6ca8cbb78c5f3123ebb623b6e9317156Selim Cinek    public void prepareFadeIn() {
41094529dff6ca8cbb78c5f3123ebb623b6e9317156Selim Cinek        super.prepareFadeIn();
41194529dff6ca8cbb78c5f3123ebb623b6e9317156Selim Cinek        setVisible(true /* visible */, false /* force */);
41294529dff6ca8cbb78c5f3123ebb623b6e9317156Selim Cinek    }
41394529dff6ca8cbb78c5f3123ebb623b6e9317156Selim Cinek
4141d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    private void resetTransformedView(View child) {
4151d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        TransformState ownState = TransformState.createFrom(child, mTransformInfo);
4161d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        ownState.resetTransformedView();
4171d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        ownState.recycle();
4181d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
4191d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
4201d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    @Override
4211d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    protected void reset() {
4221d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        super.reset();
4231d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        mMessageContainer = null;
4241d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        mMessagingLayout = null;
4251d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
4261d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek
4271d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    @Override
4281d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    public void recycle() {
4291d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        super.recycle();
4301d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        mGroupMap.clear();;
4311d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek        sInstancePool.release(this);
4321d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek    }
4331d6b50eccf3b608a34a2a92f46c7ee8b8641e0e4Selim Cinek}
434