Loading packages/SystemUI/res/values/ids.xml +6 −0 Original line number Diff line number Diff line Loading @@ -28,5 +28,11 @@ <item type="id" name="alpha_animator_end_value_tag"/> <item type="id" name="top_inset_animator_end_value_tag"/> <item type="id" name="height_animator_end_value_tag"/> <item type="id" name="translation_y_animator_start_value_tag"/> <item type="id" name="translation_z_animator_start_value_tag"/> <item type="id" name="scale_animator_start_value_tag"/> <item type="id" name="alpha_animator_start_value_tag"/> <item type="id" name="top_inset_animator_start_value_tag"/> <item type="id" name="height_animator_start_value_tag"/> </resources> packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java +140 −75 Original line number Diff line number Diff line Loading @@ -54,6 +54,12 @@ public class StackStateAnimator { private static final int TAG_END_ALPHA = R.id.alpha_animator_end_value_tag; private static final int TAG_END_HEIGHT = R.id.height_animator_end_value_tag; private static final int TAG_END_TOP_INSET = R.id.top_inset_animator_end_value_tag; private static final int TAG_START_TRANSLATION_Y = R.id.translation_y_animator_start_value_tag; private static final int TAG_START_TRANSLATION_Z = R.id.translation_z_animator_start_value_tag; private static final int TAG_START_SCALE = R.id.scale_animator_start_value_tag; private static final int TAG_START_ALPHA = R.id.alpha_animator_start_value_tag; private static final int TAG_START_HEIGHT = R.id.height_animator_start_value_tag; private static final int TAG_START_TOP_INSET = R.id.top_inset_animator_start_value_tag; private final Interpolator mFastOutSlowInInterpolator; public NotificationStackScrollLayout mHostLayout; Loading Loading @@ -139,23 +145,34 @@ public class StackStateAnimator { private void startHeightAnimation(final ExpandableView child, StackScrollState.ViewState viewState) { Integer previousStartValue = getChildTag(child, TAG_START_HEIGHT); Integer previousEndValue = getChildTag(child, TAG_END_HEIGHT); if (previousEndValue != null && previousEndValue == viewState.height) { int newEndValue = viewState.height; if (previousEndValue != null && previousEndValue == newEndValue) { return; } ValueAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_HEIGHT); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator, mAnimationFilter.animateHeight); if (newDuration <= 0) { if (!mAnimationFilter.animateHeight) { // just a local update was performed if (previousAnimator != null) { // we need to increase all animation keyframes of the previous animator by the // relative change to the end value PropertyValuesHolder[] values = previousAnimator.getValues(); int relativeDiff = newEndValue - previousEndValue; int newStartValue = previousStartValue + relativeDiff; values[0].setIntValues(newStartValue, newEndValue); child.setTag(TAG_START_HEIGHT, newStartValue); child.setTag(TAG_END_HEIGHT, newEndValue); previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime()); return; } else { // no new animation needed, let's just apply the value child.setActualHeight(viewState.height, false /* notifyListeners */); if (previousAnimator != null && !isRunning()) { onAnimationFinished(); } child.setActualHeight(newEndValue, false); return; } } ValueAnimator animator = ValueAnimator.ofInt(child.getActualHeight(), viewState.height); ValueAnimator animator = ValueAnimator.ofInt(child.getActualHeight(), newEndValue); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Loading @@ -164,6 +181,7 @@ public class StackStateAnimator { } }); animator.setInterpolator(mFastOutSlowInInterpolator); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator); animator.setDuration(newDuration); animator.addListener(getGlobalAnimationFinishedListener()); // remove the tag when the animation is finished Loading @@ -171,38 +189,49 @@ public class StackStateAnimator { @Override public void onAnimationEnd(Animator animation) { child.setTag(TAG_ANIMATOR_HEIGHT, null); child.setTag(TAG_START_HEIGHT, null); child.setTag(TAG_END_HEIGHT, null); } }); startInstantly(animator); child.setTag(TAG_ANIMATOR_HEIGHT, animator); child.setTag(TAG_END_HEIGHT, viewState.height); child.setTag(TAG_START_HEIGHT, child.getActualHeight()); child.setTag(TAG_END_HEIGHT, newEndValue); } private void startAlphaAnimation(final ExpandableView child, final StackScrollState.ViewState viewState) { final float endAlpha = viewState.alpha; Float previousStartValue = getChildTag(child,TAG_START_ALPHA); Float previousEndValue = getChildTag(child,TAG_END_ALPHA); if (previousEndValue != null && previousEndValue == endAlpha) { final float newEndValue = viewState.alpha; if (previousEndValue != null && previousEndValue == newEndValue) { return; } ObjectAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_ALPHA); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator, mAnimationFilter.animateAlpha); if (newDuration <= 0) { if (!mAnimationFilter.animateAlpha) { // just a local update was performed if (previousAnimator != null) { // we need to increase all animation keyframes of the previous animator by the // relative change to the end value PropertyValuesHolder[] values = previousAnimator.getValues(); float relativeDiff = newEndValue - previousEndValue; float newStartValue = previousStartValue + relativeDiff; values[0].setFloatValues(newStartValue, newEndValue); child.setTag(TAG_START_ALPHA, newStartValue); child.setTag(TAG_END_ALPHA, newEndValue); previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime()); return; } else { // no new animation needed, let's just apply the value child.setAlpha(endAlpha); if (endAlpha == 0) { child.setAlpha(newEndValue); if (newEndValue == 0) { child.setVisibility(View.INVISIBLE); } if (previousAnimator != null && !isRunning()) { onAnimationFinished(); } return; } ObjectAnimator animator = ObjectAnimator.ofFloat(child, View.ALPHA, child.getAlpha(), endAlpha); child.getAlpha(), newEndValue); animator.setInterpolator(mFastOutSlowInInterpolator); // Handle layer type final int currentLayerType = child.getLayerType(); Loading @@ -213,10 +242,11 @@ public class StackStateAnimator { @Override public void onAnimationEnd(Animator animation) { child.setLayerType(currentLayerType, null); if (endAlpha == 0 && !mWasCancelled) { if (newEndValue == 0 && !mWasCancelled) { child.setVisibility(View.INVISIBLE); } child.setTag(TAG_ANIMATOR_ALPHA, null); child.setTag(TAG_START_ALPHA, null); child.setTag(TAG_END_ALPHA, null); } Loading @@ -230,6 +260,7 @@ public class StackStateAnimator { mWasCancelled = false; } }); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator); animator.setDuration(newDuration); animator.addListener(getGlobalAnimationFinishedListener()); // remove the tag when the animation is finished Loading @@ -241,31 +272,42 @@ public class StackStateAnimator { }); startInstantly(animator); child.setTag(TAG_ANIMATOR_ALPHA, animator); child.setTag(TAG_END_ALPHA, endAlpha); child.setTag(TAG_START_ALPHA, child.getAlpha()); child.setTag(TAG_END_ALPHA, newEndValue); } private void startZTranslationAnimation(final ExpandableView child, final StackScrollState.ViewState viewState) { Float previousStartValue = getChildTag(child,TAG_START_TRANSLATION_Z); Float previousEndValue = getChildTag(child,TAG_END_TRANSLATION_Z); if (previousEndValue != null && previousEndValue == viewState.zTranslation) { float newEndValue = viewState.zTranslation; if (previousEndValue != null && previousEndValue == newEndValue) { return; } ObjectAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_TRANSLATION_Z); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator, mAnimationFilter.animateZ); if (newDuration <= 0) { if (!mAnimationFilter.animateZ) { // just a local update was performed if (previousAnimator != null) { // we need to increase all animation keyframes of the previous animator by the // relative change to the end value PropertyValuesHolder[] values = previousAnimator.getValues(); float relativeDiff = newEndValue - previousEndValue; float newStartValue = previousStartValue + relativeDiff; values[0].setFloatValues(newStartValue, newEndValue); child.setTag(TAG_START_TRANSLATION_Z, newStartValue); child.setTag(TAG_END_TRANSLATION_Z, newEndValue); previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime()); return; } else { // no new animation needed, let's just apply the value child.setTranslationZ(viewState.zTranslation); if (previousAnimator != null && !isRunning()) { onAnimationFinished(); child.setTranslationZ(newEndValue); } return; } ObjectAnimator animator = ObjectAnimator.ofFloat(child, View.TRANSLATION_Z, child.getTranslationZ(), viewState.zTranslation); child.getTranslationZ(), newEndValue); animator.setInterpolator(mFastOutSlowInInterpolator); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator); animator.setDuration(newDuration); animator.addListener(getGlobalAnimationFinishedListener()); // remove the tag when the animation is finished Loading @@ -273,35 +315,49 @@ public class StackStateAnimator { @Override public void onAnimationEnd(Animator animation) { child.setTag(TAG_ANIMATOR_TRANSLATION_Z, null); child.setTag(TAG_START_TRANSLATION_Z, null); child.setTag(TAG_END_TRANSLATION_Z, null); } }); startInstantly(animator); child.setTag(TAG_ANIMATOR_TRANSLATION_Z, animator); child.setTag(TAG_END_TRANSLATION_Z, viewState.zTranslation); child.setTag(TAG_START_TRANSLATION_Z, child.getTranslationZ()); child.setTag(TAG_END_TRANSLATION_Z, newEndValue); } private void startYTranslationAnimation(final ExpandableView child, StackScrollState.ViewState viewState) { Float previousStartValue = getChildTag(child,TAG_START_TRANSLATION_Y); Float previousEndValue = getChildTag(child,TAG_END_TRANSLATION_Y); if (previousEndValue != null && previousEndValue == viewState.yTranslation) { float newEndValue = viewState.yTranslation; if (previousEndValue != null && previousEndValue == newEndValue) { return; } ObjectAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_TRANSLATION_Y); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator, mAnimationFilter.animateY); if (newDuration <= 0) { if (!mAnimationFilter.animateY) { // just a local update was performed if (previousAnimator != null) { // we need to increase all animation keyframes of the previous animator by the // relative change to the end value PropertyValuesHolder[] values = previousAnimator.getValues(); float relativeDiff = newEndValue - previousEndValue; float newStartValue = previousStartValue + relativeDiff; values[0].setFloatValues(newStartValue, newEndValue); child.setTag(TAG_START_TRANSLATION_Y, newStartValue); child.setTag(TAG_END_TRANSLATION_Y, newEndValue); previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime()); return; } else { // no new animation needed, let's just apply the value child.setTranslationY(viewState.yTranslation); if (previousAnimator != null && !isRunning()) { onAnimationFinished(); } child.setTranslationY(newEndValue); return; } } ObjectAnimator animator = ObjectAnimator.ofFloat(child, View.TRANSLATION_Y, child.getTranslationY(), viewState.yTranslation); child.getTranslationY(), newEndValue); animator.setInterpolator(mFastOutSlowInInterpolator); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator); animator.setDuration(newDuration); animator.addListener(getGlobalAnimationFinishedListener()); // remove the tag when the animation is finished Loading @@ -309,39 +365,53 @@ public class StackStateAnimator { @Override public void onAnimationEnd(Animator animation) { child.setTag(TAG_ANIMATOR_TRANSLATION_Y, null); child.setTag(TAG_START_TRANSLATION_Y, null); child.setTag(TAG_END_TRANSLATION_Y, null); } }); startInstantly(animator); child.setTag(TAG_ANIMATOR_TRANSLATION_Y, animator); child.setTag(TAG_END_TRANSLATION_Y, viewState.yTranslation); child.setTag(TAG_START_TRANSLATION_Y, child.getTranslationY()); child.setTag(TAG_END_TRANSLATION_Y, newEndValue); } private void startScaleAnimation(final ExpandableView child, StackScrollState.ViewState viewState) { Float previousStartValue = getChildTag(child, TAG_START_SCALE); Float previousEndValue = getChildTag(child, TAG_END_SCALE); if (previousEndValue != null && previousEndValue == viewState.scale) { float newEndValue = viewState.scale; if (previousEndValue != null && previousEndValue == newEndValue) { return; } ObjectAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_SCALE); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator, mAnimationFilter.animateScale); if (newDuration <= 0) { if (!mAnimationFilter.animateScale) { // just a local update was performed if (previousAnimator != null) { // we need to increase all animation keyframes of the previous animator by the // relative change to the end value PropertyValuesHolder[] values = previousAnimator.getValues(); float relativeDiff = newEndValue - previousEndValue; float newStartValue = previousStartValue + relativeDiff; values[0].setFloatValues(newStartValue, newEndValue); values[1].setFloatValues(newStartValue, newEndValue); child.setTag(TAG_START_SCALE, newStartValue); child.setTag(TAG_END_SCALE, newEndValue); previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime()); return; } else { // no new animation needed, let's just apply the value child.setScaleX(viewState.scale); child.setScaleY(viewState.scale); if (previousAnimator != null && !isRunning()) { onAnimationFinished(); child.setScaleX(newEndValue); child.setScaleY(newEndValue); } return; } PropertyValuesHolder holderX = PropertyValuesHolder.ofFloat(View.SCALE_X, child.getScaleX(), viewState.scale); PropertyValuesHolder.ofFloat(View.SCALE_X, child.getScaleX(), newEndValue); PropertyValuesHolder holderY = PropertyValuesHolder.ofFloat(View.SCALE_Y, child.getScaleY(), viewState.scale); PropertyValuesHolder.ofFloat(View.SCALE_Y, child.getScaleY(), newEndValue); ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(child, holderX, holderY); animator.setInterpolator(mFastOutSlowInInterpolator); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator); animator.setDuration(newDuration); animator.addListener(getGlobalAnimationFinishedListener()); // remove the tag when the animation is finished Loading @@ -349,12 +419,14 @@ public class StackStateAnimator { @Override public void onAnimationEnd(Animator animation) { child.setTag(TAG_ANIMATOR_SCALE, null); child.setTag(TAG_START_SCALE, null); child.setTag(TAG_END_SCALE, null); } }); startInstantly(animator); child.setTag(TAG_ANIMATOR_SCALE, animator); child.setTag(TAG_END_SCALE, viewState.scale); child.setTag(TAG_START_SCALE, child.getScaleX()); child.setTag(TAG_END_SCALE, newEndValue); } /** Loading Loading @@ -408,23 +480,16 @@ public class StackStateAnimator { * Cancel the previous animator and get the duration of the new animation. * * @param previousAnimator the animator which was running before * @param newAnimationNeeded indicating whether a new animation should be started for this * property * @return the new duration */ private long cancelAnimatorAndGetNewDuration(ValueAnimator previousAnimator, boolean newAnimationNeeded) { private long cancelAnimatorAndGetNewDuration(ValueAnimator previousAnimator) { long newDuration = mCurrentLength; if (previousAnimator != null) { if (!newAnimationNeeded) { // This is only an update, no new event came in. lets just take the remaining // duration as the new duration newDuration = previousAnimator.getDuration() - previousAnimator.getCurrentPlayTime(); } // We take either the desired length of the new animation or the remaining time of // the previous animator, whichever is longer. newDuration = Math.max(previousAnimator.getDuration() - previousAnimator.getCurrentPlayTime(), newDuration); previousAnimator.cancel(); } else if (!newAnimationNeeded){ newDuration = 0; } return newDuration; } Loading Loading
packages/SystemUI/res/values/ids.xml +6 −0 Original line number Diff line number Diff line Loading @@ -28,5 +28,11 @@ <item type="id" name="alpha_animator_end_value_tag"/> <item type="id" name="top_inset_animator_end_value_tag"/> <item type="id" name="height_animator_end_value_tag"/> <item type="id" name="translation_y_animator_start_value_tag"/> <item type="id" name="translation_z_animator_start_value_tag"/> <item type="id" name="scale_animator_start_value_tag"/> <item type="id" name="alpha_animator_start_value_tag"/> <item type="id" name="top_inset_animator_start_value_tag"/> <item type="id" name="height_animator_start_value_tag"/> </resources>
packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java +140 −75 Original line number Diff line number Diff line Loading @@ -54,6 +54,12 @@ public class StackStateAnimator { private static final int TAG_END_ALPHA = R.id.alpha_animator_end_value_tag; private static final int TAG_END_HEIGHT = R.id.height_animator_end_value_tag; private static final int TAG_END_TOP_INSET = R.id.top_inset_animator_end_value_tag; private static final int TAG_START_TRANSLATION_Y = R.id.translation_y_animator_start_value_tag; private static final int TAG_START_TRANSLATION_Z = R.id.translation_z_animator_start_value_tag; private static final int TAG_START_SCALE = R.id.scale_animator_start_value_tag; private static final int TAG_START_ALPHA = R.id.alpha_animator_start_value_tag; private static final int TAG_START_HEIGHT = R.id.height_animator_start_value_tag; private static final int TAG_START_TOP_INSET = R.id.top_inset_animator_start_value_tag; private final Interpolator mFastOutSlowInInterpolator; public NotificationStackScrollLayout mHostLayout; Loading Loading @@ -139,23 +145,34 @@ public class StackStateAnimator { private void startHeightAnimation(final ExpandableView child, StackScrollState.ViewState viewState) { Integer previousStartValue = getChildTag(child, TAG_START_HEIGHT); Integer previousEndValue = getChildTag(child, TAG_END_HEIGHT); if (previousEndValue != null && previousEndValue == viewState.height) { int newEndValue = viewState.height; if (previousEndValue != null && previousEndValue == newEndValue) { return; } ValueAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_HEIGHT); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator, mAnimationFilter.animateHeight); if (newDuration <= 0) { if (!mAnimationFilter.animateHeight) { // just a local update was performed if (previousAnimator != null) { // we need to increase all animation keyframes of the previous animator by the // relative change to the end value PropertyValuesHolder[] values = previousAnimator.getValues(); int relativeDiff = newEndValue - previousEndValue; int newStartValue = previousStartValue + relativeDiff; values[0].setIntValues(newStartValue, newEndValue); child.setTag(TAG_START_HEIGHT, newStartValue); child.setTag(TAG_END_HEIGHT, newEndValue); previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime()); return; } else { // no new animation needed, let's just apply the value child.setActualHeight(viewState.height, false /* notifyListeners */); if (previousAnimator != null && !isRunning()) { onAnimationFinished(); } child.setActualHeight(newEndValue, false); return; } } ValueAnimator animator = ValueAnimator.ofInt(child.getActualHeight(), viewState.height); ValueAnimator animator = ValueAnimator.ofInt(child.getActualHeight(), newEndValue); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Loading @@ -164,6 +181,7 @@ public class StackStateAnimator { } }); animator.setInterpolator(mFastOutSlowInInterpolator); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator); animator.setDuration(newDuration); animator.addListener(getGlobalAnimationFinishedListener()); // remove the tag when the animation is finished Loading @@ -171,38 +189,49 @@ public class StackStateAnimator { @Override public void onAnimationEnd(Animator animation) { child.setTag(TAG_ANIMATOR_HEIGHT, null); child.setTag(TAG_START_HEIGHT, null); child.setTag(TAG_END_HEIGHT, null); } }); startInstantly(animator); child.setTag(TAG_ANIMATOR_HEIGHT, animator); child.setTag(TAG_END_HEIGHT, viewState.height); child.setTag(TAG_START_HEIGHT, child.getActualHeight()); child.setTag(TAG_END_HEIGHT, newEndValue); } private void startAlphaAnimation(final ExpandableView child, final StackScrollState.ViewState viewState) { final float endAlpha = viewState.alpha; Float previousStartValue = getChildTag(child,TAG_START_ALPHA); Float previousEndValue = getChildTag(child,TAG_END_ALPHA); if (previousEndValue != null && previousEndValue == endAlpha) { final float newEndValue = viewState.alpha; if (previousEndValue != null && previousEndValue == newEndValue) { return; } ObjectAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_ALPHA); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator, mAnimationFilter.animateAlpha); if (newDuration <= 0) { if (!mAnimationFilter.animateAlpha) { // just a local update was performed if (previousAnimator != null) { // we need to increase all animation keyframes of the previous animator by the // relative change to the end value PropertyValuesHolder[] values = previousAnimator.getValues(); float relativeDiff = newEndValue - previousEndValue; float newStartValue = previousStartValue + relativeDiff; values[0].setFloatValues(newStartValue, newEndValue); child.setTag(TAG_START_ALPHA, newStartValue); child.setTag(TAG_END_ALPHA, newEndValue); previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime()); return; } else { // no new animation needed, let's just apply the value child.setAlpha(endAlpha); if (endAlpha == 0) { child.setAlpha(newEndValue); if (newEndValue == 0) { child.setVisibility(View.INVISIBLE); } if (previousAnimator != null && !isRunning()) { onAnimationFinished(); } return; } ObjectAnimator animator = ObjectAnimator.ofFloat(child, View.ALPHA, child.getAlpha(), endAlpha); child.getAlpha(), newEndValue); animator.setInterpolator(mFastOutSlowInInterpolator); // Handle layer type final int currentLayerType = child.getLayerType(); Loading @@ -213,10 +242,11 @@ public class StackStateAnimator { @Override public void onAnimationEnd(Animator animation) { child.setLayerType(currentLayerType, null); if (endAlpha == 0 && !mWasCancelled) { if (newEndValue == 0 && !mWasCancelled) { child.setVisibility(View.INVISIBLE); } child.setTag(TAG_ANIMATOR_ALPHA, null); child.setTag(TAG_START_ALPHA, null); child.setTag(TAG_END_ALPHA, null); } Loading @@ -230,6 +260,7 @@ public class StackStateAnimator { mWasCancelled = false; } }); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator); animator.setDuration(newDuration); animator.addListener(getGlobalAnimationFinishedListener()); // remove the tag when the animation is finished Loading @@ -241,31 +272,42 @@ public class StackStateAnimator { }); startInstantly(animator); child.setTag(TAG_ANIMATOR_ALPHA, animator); child.setTag(TAG_END_ALPHA, endAlpha); child.setTag(TAG_START_ALPHA, child.getAlpha()); child.setTag(TAG_END_ALPHA, newEndValue); } private void startZTranslationAnimation(final ExpandableView child, final StackScrollState.ViewState viewState) { Float previousStartValue = getChildTag(child,TAG_START_TRANSLATION_Z); Float previousEndValue = getChildTag(child,TAG_END_TRANSLATION_Z); if (previousEndValue != null && previousEndValue == viewState.zTranslation) { float newEndValue = viewState.zTranslation; if (previousEndValue != null && previousEndValue == newEndValue) { return; } ObjectAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_TRANSLATION_Z); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator, mAnimationFilter.animateZ); if (newDuration <= 0) { if (!mAnimationFilter.animateZ) { // just a local update was performed if (previousAnimator != null) { // we need to increase all animation keyframes of the previous animator by the // relative change to the end value PropertyValuesHolder[] values = previousAnimator.getValues(); float relativeDiff = newEndValue - previousEndValue; float newStartValue = previousStartValue + relativeDiff; values[0].setFloatValues(newStartValue, newEndValue); child.setTag(TAG_START_TRANSLATION_Z, newStartValue); child.setTag(TAG_END_TRANSLATION_Z, newEndValue); previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime()); return; } else { // no new animation needed, let's just apply the value child.setTranslationZ(viewState.zTranslation); if (previousAnimator != null && !isRunning()) { onAnimationFinished(); child.setTranslationZ(newEndValue); } return; } ObjectAnimator animator = ObjectAnimator.ofFloat(child, View.TRANSLATION_Z, child.getTranslationZ(), viewState.zTranslation); child.getTranslationZ(), newEndValue); animator.setInterpolator(mFastOutSlowInInterpolator); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator); animator.setDuration(newDuration); animator.addListener(getGlobalAnimationFinishedListener()); // remove the tag when the animation is finished Loading @@ -273,35 +315,49 @@ public class StackStateAnimator { @Override public void onAnimationEnd(Animator animation) { child.setTag(TAG_ANIMATOR_TRANSLATION_Z, null); child.setTag(TAG_START_TRANSLATION_Z, null); child.setTag(TAG_END_TRANSLATION_Z, null); } }); startInstantly(animator); child.setTag(TAG_ANIMATOR_TRANSLATION_Z, animator); child.setTag(TAG_END_TRANSLATION_Z, viewState.zTranslation); child.setTag(TAG_START_TRANSLATION_Z, child.getTranslationZ()); child.setTag(TAG_END_TRANSLATION_Z, newEndValue); } private void startYTranslationAnimation(final ExpandableView child, StackScrollState.ViewState viewState) { Float previousStartValue = getChildTag(child,TAG_START_TRANSLATION_Y); Float previousEndValue = getChildTag(child,TAG_END_TRANSLATION_Y); if (previousEndValue != null && previousEndValue == viewState.yTranslation) { float newEndValue = viewState.yTranslation; if (previousEndValue != null && previousEndValue == newEndValue) { return; } ObjectAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_TRANSLATION_Y); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator, mAnimationFilter.animateY); if (newDuration <= 0) { if (!mAnimationFilter.animateY) { // just a local update was performed if (previousAnimator != null) { // we need to increase all animation keyframes of the previous animator by the // relative change to the end value PropertyValuesHolder[] values = previousAnimator.getValues(); float relativeDiff = newEndValue - previousEndValue; float newStartValue = previousStartValue + relativeDiff; values[0].setFloatValues(newStartValue, newEndValue); child.setTag(TAG_START_TRANSLATION_Y, newStartValue); child.setTag(TAG_END_TRANSLATION_Y, newEndValue); previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime()); return; } else { // no new animation needed, let's just apply the value child.setTranslationY(viewState.yTranslation); if (previousAnimator != null && !isRunning()) { onAnimationFinished(); } child.setTranslationY(newEndValue); return; } } ObjectAnimator animator = ObjectAnimator.ofFloat(child, View.TRANSLATION_Y, child.getTranslationY(), viewState.yTranslation); child.getTranslationY(), newEndValue); animator.setInterpolator(mFastOutSlowInInterpolator); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator); animator.setDuration(newDuration); animator.addListener(getGlobalAnimationFinishedListener()); // remove the tag when the animation is finished Loading @@ -309,39 +365,53 @@ public class StackStateAnimator { @Override public void onAnimationEnd(Animator animation) { child.setTag(TAG_ANIMATOR_TRANSLATION_Y, null); child.setTag(TAG_START_TRANSLATION_Y, null); child.setTag(TAG_END_TRANSLATION_Y, null); } }); startInstantly(animator); child.setTag(TAG_ANIMATOR_TRANSLATION_Y, animator); child.setTag(TAG_END_TRANSLATION_Y, viewState.yTranslation); child.setTag(TAG_START_TRANSLATION_Y, child.getTranslationY()); child.setTag(TAG_END_TRANSLATION_Y, newEndValue); } private void startScaleAnimation(final ExpandableView child, StackScrollState.ViewState viewState) { Float previousStartValue = getChildTag(child, TAG_START_SCALE); Float previousEndValue = getChildTag(child, TAG_END_SCALE); if (previousEndValue != null && previousEndValue == viewState.scale) { float newEndValue = viewState.scale; if (previousEndValue != null && previousEndValue == newEndValue) { return; } ObjectAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_SCALE); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator, mAnimationFilter.animateScale); if (newDuration <= 0) { if (!mAnimationFilter.animateScale) { // just a local update was performed if (previousAnimator != null) { // we need to increase all animation keyframes of the previous animator by the // relative change to the end value PropertyValuesHolder[] values = previousAnimator.getValues(); float relativeDiff = newEndValue - previousEndValue; float newStartValue = previousStartValue + relativeDiff; values[0].setFloatValues(newStartValue, newEndValue); values[1].setFloatValues(newStartValue, newEndValue); child.setTag(TAG_START_SCALE, newStartValue); child.setTag(TAG_END_SCALE, newEndValue); previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime()); return; } else { // no new animation needed, let's just apply the value child.setScaleX(viewState.scale); child.setScaleY(viewState.scale); if (previousAnimator != null && !isRunning()) { onAnimationFinished(); child.setScaleX(newEndValue); child.setScaleY(newEndValue); } return; } PropertyValuesHolder holderX = PropertyValuesHolder.ofFloat(View.SCALE_X, child.getScaleX(), viewState.scale); PropertyValuesHolder.ofFloat(View.SCALE_X, child.getScaleX(), newEndValue); PropertyValuesHolder holderY = PropertyValuesHolder.ofFloat(View.SCALE_Y, child.getScaleY(), viewState.scale); PropertyValuesHolder.ofFloat(View.SCALE_Y, child.getScaleY(), newEndValue); ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(child, holderX, holderY); animator.setInterpolator(mFastOutSlowInInterpolator); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator); animator.setDuration(newDuration); animator.addListener(getGlobalAnimationFinishedListener()); // remove the tag when the animation is finished Loading @@ -349,12 +419,14 @@ public class StackStateAnimator { @Override public void onAnimationEnd(Animator animation) { child.setTag(TAG_ANIMATOR_SCALE, null); child.setTag(TAG_START_SCALE, null); child.setTag(TAG_END_SCALE, null); } }); startInstantly(animator); child.setTag(TAG_ANIMATOR_SCALE, animator); child.setTag(TAG_END_SCALE, viewState.scale); child.setTag(TAG_START_SCALE, child.getScaleX()); child.setTag(TAG_END_SCALE, newEndValue); } /** Loading Loading @@ -408,23 +480,16 @@ public class StackStateAnimator { * Cancel the previous animator and get the duration of the new animation. * * @param previousAnimator the animator which was running before * @param newAnimationNeeded indicating whether a new animation should be started for this * property * @return the new duration */ private long cancelAnimatorAndGetNewDuration(ValueAnimator previousAnimator, boolean newAnimationNeeded) { private long cancelAnimatorAndGetNewDuration(ValueAnimator previousAnimator) { long newDuration = mCurrentLength; if (previousAnimator != null) { if (!newAnimationNeeded) { // This is only an update, no new event came in. lets just take the remaining // duration as the new duration newDuration = previousAnimator.getDuration() - previousAnimator.getCurrentPlayTime(); } // We take either the desired length of the new animation or the remaining time of // the previous animator, whichever is longer. newDuration = Math.max(previousAnimator.getDuration() - previousAnimator.getCurrentPlayTime(), newDuration); previousAnimator.cancel(); } else if (!newAnimationNeeded){ newDuration = 0; } return newDuration; } Loading