The blogger in the previous section introduced the use of AlphaAnimation and fade-in animation, which is actually just one of the four complementary animations.So in order to further understand the other interpolation animations, I would like to say that the use of Rotate Animation, which happens to work in a similar application scenario, is just described.Like there are many pictures in our life that swing from left to right, such as the pendulum of an old-fashioned pendulum swinging around a vertical axis, or people in the park swinging around on a swing, so think, well, this swing animation is really close to life.
If we think of a pendulum or swing as a line segment, with the end point above it as the center, we first rotate to the left from a vertical downward angle; turn to an angle, then rotate to the right, and rotate to the same height to the left; then rotate to the left, and wait until the segment swings to a vertical downward direction, a cycle of swinging is completed.In this way, the swing animation seems to have something to do with the rotation animation. Think carefully, this swing animation is actually connected by three rotating animations. First rotate 60 degrees to the left, then rotate 120 degrees to the right, and finally rotate 60 degrees to the left.So see if you can find ideas from the RotateAnimation source.
Analyzing the source code of RotateAnimation, we see that RotateAnimation inherits from Animation, and apart from several constructors and initializers, the applyTransformation function plays a major role.
-
protected void applyTransformation(float interpolatedTime, Transformation t) {
-
float degrees = mFromDegrees + ((mToDegrees - mFromDegrees) * interpolatedTime);
-
float scale = getScaleFactor();
-
-
if (mPivotX == 0.0f && mPivotY == 0.0f) {
-
t.getMatrix().setRotate(degrees);
-
} else {
-
t.getMatrix().setRotate(degrees, mPivotX * scale, mPivotY * scale);
-
}
-
}
The input parameter to the function, interpolatedTime, represents the interpolation time (percentage), and the degrees inside the code represent the degrees of the position at the interpolation time, regardless of scale default 1.mFromDegrees denotes the starting degree of the animation, and mToDegrees denotes the ending degree of the animation, which are parameters passed in at initialization.The mPivotX and mPivotY in the latter code are the first X-coordinate representing the center of rotation, and the second Y-coordinate representing the center of rotation. By default, the top left vertex of the graphic is the center (mPivotX=0.0f, mPivotY=0.0f).If it is not the default center, rotate it using the specified coordinates as the center.
From this point of view, there are several places to adjust the swing animation:
1. There are only two degrees when the rotation animation is initialized: the starting degree and the ending degree.The swing animation takes three parameters: the middle degree (both start and end), the degree to the left, and the degree to the right.
2. Estimating the current degree based on the interpolation time, the rocking animation needs to make three branch judgments (corresponding to the previously mentioned rocking animation is made up of three rotating animations).If the whole animation lasts for 4 seconds, then the animation is rotated to the left between 0-1 seconds, with the starting degree being intermediate and the ending degree being degrees to the left; the animation is rotated to the right between 1-3 seconds, with the starting degree being degrees to the left and the ending degree being degrees to the right; the animation is rotated to the left between 3-4 seconds, with the starting degree being degrees to the right and the ending degree being degrees.Number is in the middle.
Finished analysis, Paste Modified rocking animation code
-
import android.view.animation.Animation;
-
import android.view.animation.Transformation;
-
-
public class SwingAnimation extends Animation {
-
private float mMiddleDegrees;
-
private float mLeftDegrees;
-
private float mRightDegrees;
-
private int mPivotXType = ABSOLUTE;
-
private int mPivotYType = ABSOLUTE;
-
private float mPivotXValue = 0.0f;
-
private float mPivotYValue = 0.0f;
-
private float mPivotX;
-
private float mPivotY;
-
-
public SwingAnimation(float middleDegrees, float leftDegrees, float rightDegrees) {
-
mMiddleDegrees = middleDegrees;
-
mLeftDegrees = leftDegrees;
-
mRightDegrees = rightDegrees;
-
mPivotX = 0.0f;
-
mPivotY = 0.0f;
-
}
-
-
public SwingAnimation(float middleDegrees, float leftDegrees, float rightDegrees, float pivotX, float pivotY) {
-
mMiddleDegrees = middleDegrees;
-
mLeftDegrees = leftDegrees;
-
mRightDegrees = rightDegrees;
-
mPivotXType = ABSOLUTE;
-
mPivotYType = ABSOLUTE;
-
mPivotXValue = pivotX;
-
mPivotYValue = pivotY;
-
initializePivotPoint();
-
}
-
-
public SwingAnimation(float middleDegrees, float leftDegrees, float rightDegrees, int pivotXType, float pivotXValue,
-
int pivotYType, float pivotYValue) {
-
mMiddleDegrees = middleDegrees;
-
mLeftDegrees = leftDegrees;
-
mRightDegrees = rightDegrees;
-
mPivotXValue = pivotXValue;
-
mPivotXType = pivotXType;
-
mPivotYValue = pivotYValue;
-
mPivotYType = pivotYType;
-
initializePivotPoint();
-
}
-
-
private void initializePivotPoint() {
-
if (mPivotXType == ABSOLUTE) {
-
mPivotX = mPivotXValue;
-
}
-
if (mPivotYType == ABSOLUTE) {
-
mPivotY = mPivotYValue;
-
}
-
}
-
-
@Override
-
protected void applyTransformation(float interpolatedTime, Transformation t) {
-
float degrees;
-
float leftPos = (float) (1.0/4.0);
-
float rightPos = (float) (3.0/4.0);
-
if (interpolatedTime <= leftPos) {
-
degrees = mMiddleDegrees + ((mLeftDegrees - mMiddleDegrees) * interpolatedTime * 4);
-
} else if (interpolatedTime > leftPos && interpolatedTime < rightPos) {
-
degrees = mLeftDegrees + ((mRightDegrees - mLeftDegrees) * (interpolatedTime-leftPos) * 2);
-
} else {
-
degrees = mRightDegrees + ((mMiddleDegrees - mRightDegrees) * (interpolatedTime-rightPos) * 4);
-
}
-
System.out.println("degrees="+degrees);
-
-
float scale = getScaleFactor();
-
if (mPivotX == 0.0f && mPivotY == 0.0f) {
-
t.getMatrix().setRotate(degrees);
-
} else {
-
t.getMatrix().setRotate(degrees, mPivotX * scale, mPivotY * scale);
-
}
-
}
-
-
@Override
-
public void initialize(int width, int height, int parentWidth, int parentHeight) {
-
super.initialize(width, height, parentWidth, parentHeight);
-
mPivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth);
-
mPivotY = resolveSize(mPivotYType, mPivotYValue, height, parentHeight);
-
}
-
}
The code called is as follows
-
import com.example.exmswing.ui.SwingAnimation;
-
-
import android.app.Activity;
-
import android.os.Bundle;
-
import android.view.View;
-
import android.view.View.OnClickListener;
-
import android.view.animation.Animation;
-
import android.widget.Button;
-
import android.widget.ImageView;
-
-
public class MainActivity extends Activity implements OnClickListener {
-
-
private ImageView iv_swing;
-
private SwingAnimation swingAnimation;
-
-
@Override
-
protected void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
setContentView(R.layout.activity_main);
-
-
Button btn_play = (Button) findViewById(R.id.btn_play);
-
btn_play.setOnClickListener(this);
-
iv_swing = (ImageView) findViewById(R.id.iv_swing);
-
-
-
-
-
swingAnimation = new SwingAnimation(
-
0f, 60f, -60f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.0f);
-
swingAnimation.setDuration(4000);
-
swingAnimation.setRepeatCount(0);
-
swingAnimation.setFillAfter(false);
-
swingAnimation.setStartOffset(500);
-
}
-
-
@Override
-
public void onClick(View v) {
-
if (v.getId() == R.id.btn_play) {
-
iv_swing.startAnimation(swingAnimation);
-
}
-
}
-
-
}
Below is the effect of the swing animation

Click to download the swing animation code used in this article
Click here to see the full catalog of Android Development Notes