Reputation: 3357
I have a circle that I want to bounce, so it would expand in width, and collapse in height, then the reverse and the same for a few times. That all works with a few ScaleAnimations in a row. The problem is, that I want pivotY to be the bottom of the view. In this case every time a new animation starts it'll reset the pivot point to the center. Here's my code:
bounceAnimationPartOne = new ScaleAnimation(1.0f, 1.0f, 1.62f, 0.62f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 1.0f);
bounceAnimationPartOne.setDuration(45);
bounceAnimationPartOne.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
view.startAnimation(bounceAnimationPartTwo);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
bounceAnimationPartTwo = new ScaleAnimation(1.62f, 0.62f, 0.76f, 1.3f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 1.0f);
bounceAnimationPartTwo.setDuration(90);
bounceAnimationPartTwo.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
view.startAnimation(bounceAnimationPartThree);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
bounceAnimationPartThree = new ScaleAnimation(0.76f, 1.3f, 1.23f, 0.81f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 1.0f);
bounceAnimationPartThree.setDuration(105);
bounceAnimationPartThree.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
view.startAnimation(bounceAnimationPartFour);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
bounceAnimationPartFour = new ScaleAnimation(1.23f, 0.81f, 1.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 1.0f);
bounceAnimationPartFour.setDuration(60);
Upvotes: 1
Views: 1290
Reputation: 3357
I ended up writing my own custom Animation that basically does 4 scale animations in a row:
public class BounceAnimation extends Animation {
private final List<Float> expansionValuesX;
private final List<Float> expansionValuesY;
private final List<Float> timing;
private int currentTimingIndex;
private float currentTimingSum;
private float pivotX;
private float pivotY;
public BounceAnimation(List<Float> expansionValuesX, List<Float> expansionValuesY, List<Float> timing, int duration) {
this.expansionValuesX = expansionValuesX;
this.expansionValuesY = expansionValuesY;
this.timing = timing;
setDuration(duration);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
float sx = 1.0f;
float sy = 1.0f;
if (currentTimingIndex < timing.size() - 1 && interpolatedTime >= currentTimingSum + timing.get(currentTimingIndex)) {
currentTimingSum += timing.get(currentTimingIndex);
currentTimingIndex++;
}
float currentFromX = expansionValuesX.get(currentTimingIndex);
float currentFromY = expansionValuesY.get(currentTimingIndex);
float currentToX = expansionValuesX.get(currentTimingIndex + 1);
float currentToY = expansionValuesY.get(currentTimingIndex + 1);
float currentInterpolatedTime = (interpolatedTime - currentTimingSum) / timing.get(currentTimingIndex);
if (currentFromX != 1.0f || currentToX != 1.0f) {
sx = currentFromX + ((currentToX - currentFromX) * currentInterpolatedTime);
}
if (currentFromY != 1.0f || currentToY != 1.0f) {
sy = currentFromY + ((currentToY - currentFromY) * currentInterpolatedTime);
}
if (pivotX == 0 && pivotY == 0) {
t.getMatrix().setScale(sx, sy);
} else {
t.getMatrix().setScale(sx, sy, pivotX, pivotY);
}
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
pivotX = resolveSize(Animation.RELATIVE_TO_SELF, 0.5f, width, parentWidth);
pivotY = resolveSize(Animation.RELATIVE_TO_SELF, 1.0f, height, parentHeight);
currentTimingIndex = 0;
currentTimingSum = 0;
}
}
Upvotes: 1
Reputation: 9299
Just because you animate something doesn't mean you have changed it (see previous discussion).
You may want to modify the onAnimationEnd()
method to make the effect of your animations permanent before starting another animation.
Alternatively, use an AnimationSet and set the startOffset for the second and third animations in the set. Or, even easier, use a AnimatorSet.Builder.
Upvotes: 0