Loading packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java +2 −1 Original line number Diff line number Diff line Loading @@ -56,7 +56,8 @@ public class CrossFadeHelper { view.animate() .alpha(1f) .setDuration(ANIMATION_DURATION_LENGTH) .setInterpolator(PhoneStatusBar.ALPHA_IN); .setInterpolator(PhoneStatusBar.ALPHA_IN) .withEndAction(null); if (view.hasOverlappingRendering()) { view.animate().withLayer(); } Loading packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java +37 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ public class ViewTransformationHelper implements TransformableView { private final Handler mHandler = new Handler(); private ArrayMap<Integer, View> mTransformedViews = new ArrayMap<>(); private ArrayMap<Integer, CustomTransformation> mCustomTransformations = new ArrayMap<>(); public void addTransformedView(int key, View transformedView) { mTransformedViews.put(key, transformedView); Loading @@ -44,6 +45,10 @@ public class ViewTransformationHelper implements TransformableView { mTransformedViews.clear(); } public void setCustomTransformation(CustomTransformation transformation, int viewType) { mCustomTransformations.put(viewType, transformation); } @Override public TransformState getCurrentState(int fadingView) { View view = mTransformedViews.get(fadingView); Loading @@ -59,6 +64,13 @@ public class ViewTransformationHelper implements TransformableView { for (Integer viewType : mTransformedViews.keySet()) { TransformState ownState = getCurrentState(viewType); if (ownState != null) { CustomTransformation customTransformation = mCustomTransformations.get(viewType); if (customTransformation != null && customTransformation.transformTo( ownState, notification, runnable)) { ownState.recycle(); runnable = null; continue; } TransformState otherState = notification.getCurrentState(viewType); if (otherState != null) { boolean run = ownState.transformViewTo(otherState, runnable); Loading Loading @@ -86,6 +98,12 @@ public class ViewTransformationHelper implements TransformableView { for (Integer viewType : mTransformedViews.keySet()) { TransformState ownState = getCurrentState(viewType); if (ownState != null) { CustomTransformation customTransformation = mCustomTransformations.get(viewType); if (customTransformation != null && customTransformation.transformFrom( ownState, notification)) { ownState.recycle(); continue; } TransformState otherState = notification.getCurrentState(viewType); if (otherState != null) { ownState.transformViewFrom(otherState); Loading Loading @@ -154,4 +172,23 @@ public class ViewTransformationHelper implements TransformableView { } } } public interface CustomTransformation { /** * Transform a state to the given view * @param ownState the state to transform * @param notification the view to transform to * @return whether a custom transformation is performed */ boolean transformTo(TransformState ownState, TransformableView notification, Runnable endRunnable); /** * Transform to this state from the given view * @param ownState the state to transform to * @param notification the view to transform from * @return whether a custom transformation is performed */ boolean transformFrom(TransformState ownState, TransformableView notification); } } packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationView.java +31 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.widget.TextView; import com.android.keyguard.AlphaOptimizedLinearLayout; import com.android.systemui.R; import com.android.systemui.ViewInvertHelper; import com.android.systemui.statusbar.CrossFadeHelper; import com.android.systemui.statusbar.TransformableView; import com.android.systemui.statusbar.ViewTransformationHelper; import com.android.systemui.statusbar.phone.NotificationPanelView; Loading Loading @@ -69,6 +70,36 @@ public class HybridNotificationView extends AlphaOptimizedLinearLayout mTextView = (TextView) findViewById(R.id.notification_text); mInvertHelper = new ViewInvertHelper(this, NotificationPanelView.DOZE_ANIMATION_DURATION); mTransformationHelper = new ViewTransformationHelper(); mTransformationHelper.setCustomTransformation( new ViewTransformationHelper.CustomTransformation() { @Override public boolean transformTo(TransformState ownState, TransformableView notification, Runnable endRunnable) { // We want to transform to the same y location as the title TransformState otherState = notification.getCurrentState( TRANSFORMING_VIEW_TITLE); CrossFadeHelper.fadeOut(mTextView, endRunnable); if (otherState != null) { ownState.animateViewVerticalTo(otherState, endRunnable); otherState.recycle(); } return true; } @Override public boolean transformFrom(TransformState ownState, TransformableView notification) { // We want to transform from the same y location as the title TransformState otherState = notification.getCurrentState( TRANSFORMING_VIEW_TITLE); CrossFadeHelper.fadeIn(mTextView); if (otherState != null) { ownState.animateViewVerticalFrom(otherState); otherState.recycle(); } return true; } }, TRANSFORMING_VIEW_TEXT); mTransformationHelper.addTransformedView(TRANSFORMING_VIEW_TITLE, mTitleView); mTransformationHelper.addTransformedView(TRANSFORMING_VIEW_TEXT, mTextView); } Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java +73 −0 Original line number Diff line number Diff line Loading @@ -25,7 +25,9 @@ import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; import com.android.systemui.statusbar.CrossFadeHelper; import com.android.systemui.statusbar.TransformableView; import com.android.systemui.statusbar.ViewTransformationHelper; /** * Wraps a notification view inflated from a template. Loading @@ -41,6 +43,77 @@ public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapp protected NotificationTemplateViewWrapper(Context ctx, View view) { super(ctx, view); mTransformationHelper.setCustomTransformation( new ViewTransformationHelper.CustomTransformation() { @Override public boolean transformTo(TransformState ownState, TransformableView notification, final Runnable endRunnable) { if (!(notification instanceof HybridNotificationView)) { return false; } TransformState otherState = notification.getCurrentState( TRANSFORMING_VIEW_TITLE); CrossFadeHelper.fadeOut(mText, endRunnable); if (otherState != null) { int[] otherStablePosition = otherState.getLaidOutLocationOnScreen(); int[] ownPosition = ownState.getLaidOutLocationOnScreen(); mText.animate() .translationY((otherStablePosition[1] + otherState.getTransformedView().getHeight() - ownPosition[1]) * 0.33f) .setDuration(CrossFadeHelper.ANIMATION_DURATION_LENGTH) .setInterpolator(TransformState.FAST_OUT_SLOW_IN) .withEndAction(new Runnable() { @Override public void run() { if (endRunnable != null) { endRunnable.run(); } TransformState.setClippingDeactivated(mText, false); } }); TransformState.setClippingDeactivated(mText, true); otherState.recycle(); } return true; } @Override public boolean transformFrom(TransformState ownState, TransformableView notification) { if (!(notification instanceof HybridNotificationView)) { return false; } TransformState otherState = notification.getCurrentState( TRANSFORMING_VIEW_TITLE); boolean isVisible = mText.getVisibility() == View.VISIBLE; CrossFadeHelper.fadeIn(mText); if (otherState != null) { int[] otherStablePosition = otherState.getLaidOutLocationOnScreen(); int[] ownStablePosition = ownState.getLaidOutLocationOnScreen(); if (!isVisible) { mText.setTranslationY((otherStablePosition[1] + otherState.getTransformedView().getHeight() - ownStablePosition[1]) * 0.33f); } mText.animate() .translationY(0) .setDuration(CrossFadeHelper.ANIMATION_DURATION_LENGTH) .setInterpolator(TransformState.FAST_OUT_SLOW_IN) .withEndAction(new Runnable() { @Override public void run() { TransformState.setClippingDeactivated(mText, false); } }); TransformState.setClippingDeactivated(mText, true); otherState.recycle(); } return true; } }, TRANSFORMING_VIEW_TEXT); } private void resolveTemplateViews(StatusBarNotification notification) { Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java +63 −15 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import android.view.NotificationHeaderView; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; Loading @@ -35,10 +37,15 @@ import com.android.systemui.statusbar.ExpandableNotificationRow; */ public class TransformState { private static Pools.SimplePool<TransformState> sInstancePool = new Pools.SimplePool<>(40); private static final int ANIMATE_X = 0x1; private static final int ANIMATE_Y = 0x10; private static final int ANIMATE_ALL = ANIMATE_X | ANIMATE_Y; private static final int CLIP_CLIPPING_SET = R.id.clip_children_set_tag; private static final int CLIP_CHILDREN_TAG = R.id.clip_children_tag; private static final int CLIP_TO_PADDING = R.id.clip_to_padding_tag; public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f); private static Pools.SimplePool<TransformState> sInstancePool = new Pools.SimplePool<>(40); protected View mTransformedView; private int[] mOwnPosition = new int[2]; Loading @@ -59,15 +66,32 @@ public class TransformState { } else { CrossFadeHelper.fadeIn(mTransformedView); } animateViewFrom(otherState); } public void animateViewFrom(TransformState otherState) { animateViewFrom(otherState, ANIMATE_ALL); } public void animateViewVerticalFrom(TransformState otherState) { animateViewFrom(otherState, ANIMATE_Y); } private void animateViewFrom(TransformState otherState, int animationFlags) { final View transformedView = mTransformedView; // lets animate the positions correctly int[] otherPosition = otherState.getLocationOnScreen(); int[] ownStablePosition = getLaidOutLocationOnScreen(); mTransformedView.setTranslationX(otherPosition[0] - ownStablePosition[0]); mTransformedView.setTranslationY(otherPosition[1] - ownStablePosition[1]); mTransformedView.animate() .translationX(0) .translationY(0) if ((animationFlags & ANIMATE_X) != 0) { transformedView.setTranslationX(otherPosition[0] - ownStablePosition[0]); transformedView.animate().translationX(0); } if ((animationFlags & ANIMATE_Y) != 0) { transformedView.setTranslationY(otherPosition[1] - ownStablePosition[1]); transformedView.animate().translationY(0); } transformedView.animate() .setInterpolator(TransformState.FAST_OUT_SLOW_IN) .setDuration(CrossFadeHelper.ANIMATION_DURATION_LENGTH) .withEndAction(new Runnable() { @Override Loading @@ -75,7 +99,7 @@ public class TransformState { setClippingDeactivated(transformedView, false); } }); setClippingDeactivated(mTransformedView, true); setClippingDeactivated(transformedView, true); } /** Loading @@ -94,13 +118,34 @@ public class TransformState { } else { CrossFadeHelper.fadeOut(mTransformedView, endRunnable); } animateViewTo(otherState, endRunnable); return true; } public void animateViewTo(TransformState otherState, Runnable endRunnable) { animateViewTo(otherState, endRunnable, ANIMATE_ALL); } public void animateViewVerticalTo(TransformState otherState, Runnable endRunnable) { animateViewTo(otherState, endRunnable, ANIMATE_Y); } private void animateViewTo(TransformState otherState, final Runnable endRunnable, int animationFlags) { // lets animate the positions correctly int[] otherStablePosition = otherState.getLaidOutLocationOnScreen(); int[] ownPosition = getLaidOutLocationOnScreen(); final View transformedView = mTransformedView; mTransformedView.animate() .translationX(otherStablePosition[0] - ownPosition[0]) .translationY(otherStablePosition[1] - ownPosition[1]) if ((animationFlags & ANIMATE_X) != 0) { transformedView.animate() .translationX(otherStablePosition[0] - ownPosition[0]); } if ((animationFlags & ANIMATE_Y) != 0) { transformedView.animate() .translationY(otherStablePosition[1] - ownPosition[1]); } transformedView.animate() .setInterpolator(TransformState.FAST_OUT_SLOW_IN) .setDuration(CrossFadeHelper.ANIMATION_DURATION_LENGTH) .withEndAction(new Runnable() { @Override Loading @@ -111,11 +156,10 @@ public class TransformState { setClippingDeactivated(transformedView, false); } }); setClippingDeactivated(mTransformedView, true); return true; setClippingDeactivated(transformedView, true); } private void setClippingDeactivated(final View transformedView, boolean deactivated) { public static void setClippingDeactivated(final View transformedView, boolean deactivated) { ViewGroup view = (ViewGroup) transformedView.getParent(); while (true) { ArraySet<View> clipSet = (ArraySet<View>) view.getTag(CLIP_CLIPPING_SET); Loading Loading @@ -167,14 +211,14 @@ public class TransformState { } } private int[] getLaidOutLocationOnScreen() { public int[] getLaidOutLocationOnScreen() { int[] location = getLocationOnScreen(); location[0] -= mTransformedView.getTranslationX(); location[1] -= mTransformedView.getTranslationY(); return location; } private int[] getLocationOnScreen() { public int[] getLocationOnScreen() { mTransformedView.getLocationOnScreen(mOwnPosition); return mOwnPosition; } Loading Loading @@ -240,4 +284,8 @@ public class TransformState { } return new TransformState(); } public View getTransformedView() { return mTransformedView; } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java +2 −1 Original line number Diff line number Diff line Loading @@ -56,7 +56,8 @@ public class CrossFadeHelper { view.animate() .alpha(1f) .setDuration(ANIMATION_DURATION_LENGTH) .setInterpolator(PhoneStatusBar.ALPHA_IN); .setInterpolator(PhoneStatusBar.ALPHA_IN) .withEndAction(null); if (view.hasOverlappingRendering()) { view.animate().withLayer(); } Loading
packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java +37 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ public class ViewTransformationHelper implements TransformableView { private final Handler mHandler = new Handler(); private ArrayMap<Integer, View> mTransformedViews = new ArrayMap<>(); private ArrayMap<Integer, CustomTransformation> mCustomTransformations = new ArrayMap<>(); public void addTransformedView(int key, View transformedView) { mTransformedViews.put(key, transformedView); Loading @@ -44,6 +45,10 @@ public class ViewTransformationHelper implements TransformableView { mTransformedViews.clear(); } public void setCustomTransformation(CustomTransformation transformation, int viewType) { mCustomTransformations.put(viewType, transformation); } @Override public TransformState getCurrentState(int fadingView) { View view = mTransformedViews.get(fadingView); Loading @@ -59,6 +64,13 @@ public class ViewTransformationHelper implements TransformableView { for (Integer viewType : mTransformedViews.keySet()) { TransformState ownState = getCurrentState(viewType); if (ownState != null) { CustomTransformation customTransformation = mCustomTransformations.get(viewType); if (customTransformation != null && customTransformation.transformTo( ownState, notification, runnable)) { ownState.recycle(); runnable = null; continue; } TransformState otherState = notification.getCurrentState(viewType); if (otherState != null) { boolean run = ownState.transformViewTo(otherState, runnable); Loading Loading @@ -86,6 +98,12 @@ public class ViewTransformationHelper implements TransformableView { for (Integer viewType : mTransformedViews.keySet()) { TransformState ownState = getCurrentState(viewType); if (ownState != null) { CustomTransformation customTransformation = mCustomTransformations.get(viewType); if (customTransformation != null && customTransformation.transformFrom( ownState, notification)) { ownState.recycle(); continue; } TransformState otherState = notification.getCurrentState(viewType); if (otherState != null) { ownState.transformViewFrom(otherState); Loading Loading @@ -154,4 +172,23 @@ public class ViewTransformationHelper implements TransformableView { } } } public interface CustomTransformation { /** * Transform a state to the given view * @param ownState the state to transform * @param notification the view to transform to * @return whether a custom transformation is performed */ boolean transformTo(TransformState ownState, TransformableView notification, Runnable endRunnable); /** * Transform to this state from the given view * @param ownState the state to transform to * @param notification the view to transform from * @return whether a custom transformation is performed */ boolean transformFrom(TransformState ownState, TransformableView notification); } }
packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationView.java +31 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.widget.TextView; import com.android.keyguard.AlphaOptimizedLinearLayout; import com.android.systemui.R; import com.android.systemui.ViewInvertHelper; import com.android.systemui.statusbar.CrossFadeHelper; import com.android.systemui.statusbar.TransformableView; import com.android.systemui.statusbar.ViewTransformationHelper; import com.android.systemui.statusbar.phone.NotificationPanelView; Loading Loading @@ -69,6 +70,36 @@ public class HybridNotificationView extends AlphaOptimizedLinearLayout mTextView = (TextView) findViewById(R.id.notification_text); mInvertHelper = new ViewInvertHelper(this, NotificationPanelView.DOZE_ANIMATION_DURATION); mTransformationHelper = new ViewTransformationHelper(); mTransformationHelper.setCustomTransformation( new ViewTransformationHelper.CustomTransformation() { @Override public boolean transformTo(TransformState ownState, TransformableView notification, Runnable endRunnable) { // We want to transform to the same y location as the title TransformState otherState = notification.getCurrentState( TRANSFORMING_VIEW_TITLE); CrossFadeHelper.fadeOut(mTextView, endRunnable); if (otherState != null) { ownState.animateViewVerticalTo(otherState, endRunnable); otherState.recycle(); } return true; } @Override public boolean transformFrom(TransformState ownState, TransformableView notification) { // We want to transform from the same y location as the title TransformState otherState = notification.getCurrentState( TRANSFORMING_VIEW_TITLE); CrossFadeHelper.fadeIn(mTextView); if (otherState != null) { ownState.animateViewVerticalFrom(otherState); otherState.recycle(); } return true; } }, TRANSFORMING_VIEW_TEXT); mTransformationHelper.addTransformedView(TRANSFORMING_VIEW_TITLE, mTitleView); mTransformationHelper.addTransformedView(TRANSFORMING_VIEW_TEXT, mTextView); } Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java +73 −0 Original line number Diff line number Diff line Loading @@ -25,7 +25,9 @@ import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; import com.android.systemui.statusbar.CrossFadeHelper; import com.android.systemui.statusbar.TransformableView; import com.android.systemui.statusbar.ViewTransformationHelper; /** * Wraps a notification view inflated from a template. Loading @@ -41,6 +43,77 @@ public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapp protected NotificationTemplateViewWrapper(Context ctx, View view) { super(ctx, view); mTransformationHelper.setCustomTransformation( new ViewTransformationHelper.CustomTransformation() { @Override public boolean transformTo(TransformState ownState, TransformableView notification, final Runnable endRunnable) { if (!(notification instanceof HybridNotificationView)) { return false; } TransformState otherState = notification.getCurrentState( TRANSFORMING_VIEW_TITLE); CrossFadeHelper.fadeOut(mText, endRunnable); if (otherState != null) { int[] otherStablePosition = otherState.getLaidOutLocationOnScreen(); int[] ownPosition = ownState.getLaidOutLocationOnScreen(); mText.animate() .translationY((otherStablePosition[1] + otherState.getTransformedView().getHeight() - ownPosition[1]) * 0.33f) .setDuration(CrossFadeHelper.ANIMATION_DURATION_LENGTH) .setInterpolator(TransformState.FAST_OUT_SLOW_IN) .withEndAction(new Runnable() { @Override public void run() { if (endRunnable != null) { endRunnable.run(); } TransformState.setClippingDeactivated(mText, false); } }); TransformState.setClippingDeactivated(mText, true); otherState.recycle(); } return true; } @Override public boolean transformFrom(TransformState ownState, TransformableView notification) { if (!(notification instanceof HybridNotificationView)) { return false; } TransformState otherState = notification.getCurrentState( TRANSFORMING_VIEW_TITLE); boolean isVisible = mText.getVisibility() == View.VISIBLE; CrossFadeHelper.fadeIn(mText); if (otherState != null) { int[] otherStablePosition = otherState.getLaidOutLocationOnScreen(); int[] ownStablePosition = ownState.getLaidOutLocationOnScreen(); if (!isVisible) { mText.setTranslationY((otherStablePosition[1] + otherState.getTransformedView().getHeight() - ownStablePosition[1]) * 0.33f); } mText.animate() .translationY(0) .setDuration(CrossFadeHelper.ANIMATION_DURATION_LENGTH) .setInterpolator(TransformState.FAST_OUT_SLOW_IN) .withEndAction(new Runnable() { @Override public void run() { TransformState.setClippingDeactivated(mText, false); } }); TransformState.setClippingDeactivated(mText, true); otherState.recycle(); } return true; } }, TRANSFORMING_VIEW_TEXT); } private void resolveTemplateViews(StatusBarNotification notification) { Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java +63 −15 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import android.view.NotificationHeaderView; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; Loading @@ -35,10 +37,15 @@ import com.android.systemui.statusbar.ExpandableNotificationRow; */ public class TransformState { private static Pools.SimplePool<TransformState> sInstancePool = new Pools.SimplePool<>(40); private static final int ANIMATE_X = 0x1; private static final int ANIMATE_Y = 0x10; private static final int ANIMATE_ALL = ANIMATE_X | ANIMATE_Y; private static final int CLIP_CLIPPING_SET = R.id.clip_children_set_tag; private static final int CLIP_CHILDREN_TAG = R.id.clip_children_tag; private static final int CLIP_TO_PADDING = R.id.clip_to_padding_tag; public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f); private static Pools.SimplePool<TransformState> sInstancePool = new Pools.SimplePool<>(40); protected View mTransformedView; private int[] mOwnPosition = new int[2]; Loading @@ -59,15 +66,32 @@ public class TransformState { } else { CrossFadeHelper.fadeIn(mTransformedView); } animateViewFrom(otherState); } public void animateViewFrom(TransformState otherState) { animateViewFrom(otherState, ANIMATE_ALL); } public void animateViewVerticalFrom(TransformState otherState) { animateViewFrom(otherState, ANIMATE_Y); } private void animateViewFrom(TransformState otherState, int animationFlags) { final View transformedView = mTransformedView; // lets animate the positions correctly int[] otherPosition = otherState.getLocationOnScreen(); int[] ownStablePosition = getLaidOutLocationOnScreen(); mTransformedView.setTranslationX(otherPosition[0] - ownStablePosition[0]); mTransformedView.setTranslationY(otherPosition[1] - ownStablePosition[1]); mTransformedView.animate() .translationX(0) .translationY(0) if ((animationFlags & ANIMATE_X) != 0) { transformedView.setTranslationX(otherPosition[0] - ownStablePosition[0]); transformedView.animate().translationX(0); } if ((animationFlags & ANIMATE_Y) != 0) { transformedView.setTranslationY(otherPosition[1] - ownStablePosition[1]); transformedView.animate().translationY(0); } transformedView.animate() .setInterpolator(TransformState.FAST_OUT_SLOW_IN) .setDuration(CrossFadeHelper.ANIMATION_DURATION_LENGTH) .withEndAction(new Runnable() { @Override Loading @@ -75,7 +99,7 @@ public class TransformState { setClippingDeactivated(transformedView, false); } }); setClippingDeactivated(mTransformedView, true); setClippingDeactivated(transformedView, true); } /** Loading @@ -94,13 +118,34 @@ public class TransformState { } else { CrossFadeHelper.fadeOut(mTransformedView, endRunnable); } animateViewTo(otherState, endRunnable); return true; } public void animateViewTo(TransformState otherState, Runnable endRunnable) { animateViewTo(otherState, endRunnable, ANIMATE_ALL); } public void animateViewVerticalTo(TransformState otherState, Runnable endRunnable) { animateViewTo(otherState, endRunnable, ANIMATE_Y); } private void animateViewTo(TransformState otherState, final Runnable endRunnable, int animationFlags) { // lets animate the positions correctly int[] otherStablePosition = otherState.getLaidOutLocationOnScreen(); int[] ownPosition = getLaidOutLocationOnScreen(); final View transformedView = mTransformedView; mTransformedView.animate() .translationX(otherStablePosition[0] - ownPosition[0]) .translationY(otherStablePosition[1] - ownPosition[1]) if ((animationFlags & ANIMATE_X) != 0) { transformedView.animate() .translationX(otherStablePosition[0] - ownPosition[0]); } if ((animationFlags & ANIMATE_Y) != 0) { transformedView.animate() .translationY(otherStablePosition[1] - ownPosition[1]); } transformedView.animate() .setInterpolator(TransformState.FAST_OUT_SLOW_IN) .setDuration(CrossFadeHelper.ANIMATION_DURATION_LENGTH) .withEndAction(new Runnable() { @Override Loading @@ -111,11 +156,10 @@ public class TransformState { setClippingDeactivated(transformedView, false); } }); setClippingDeactivated(mTransformedView, true); return true; setClippingDeactivated(transformedView, true); } private void setClippingDeactivated(final View transformedView, boolean deactivated) { public static void setClippingDeactivated(final View transformedView, boolean deactivated) { ViewGroup view = (ViewGroup) transformedView.getParent(); while (true) { ArraySet<View> clipSet = (ArraySet<View>) view.getTag(CLIP_CLIPPING_SET); Loading Loading @@ -167,14 +211,14 @@ public class TransformState { } } private int[] getLaidOutLocationOnScreen() { public int[] getLaidOutLocationOnScreen() { int[] location = getLocationOnScreen(); location[0] -= mTransformedView.getTranslationX(); location[1] -= mTransformedView.getTranslationY(); return location; } private int[] getLocationOnScreen() { public int[] getLocationOnScreen() { mTransformedView.getLocationOnScreen(mOwnPosition); return mOwnPosition; } Loading Loading @@ -240,4 +284,8 @@ public class TransformState { } return new TransformState(); } public View getTransformedView() { return mTransformedView; } }