Android Realization of Simple Operation of Paper Airplane
- 2021-09-11 21:11:34
- OfStack
In the project, we asked to do the function of a paper airplane: when this interface is opened, four paper airplanes will fly in from the left side of the screen, and then reach their own positions to sit up and down, while clouds will constantly float from the right side of the screen to the left side of the screen. When you click on one of the paper airplanes, the paper airplane first flies up and out of the screen, then flies in from the left side. When the airplane returns to its original position, a message box pops up. The following code is directly listed:
1. First, customize an RelativeLayout, the main purpose of which is to make the entry animation of the aircraft:
public class PaperPlaneLayout extends RelativeLayout implements View.OnClickListener{
private OnClickListener mOnClickListener;
// Customize the width and height of the layout
private int mHeight;
private int mWidth;
private LayoutParams lp;
private Drawable[] drawables;
private Random random = new Random();
// Get 4 Width and height of paper airplane
private int dHeight;
private int dWidth;
private int mX;
private int mY;
public PaperPlaneLayout(Context context) {
super(context);
init();
}
public PaperPlaneLayout(Context context,
AttributeSet attrs) {
super(context, attrs);
init();
}
public PaperPlaneLayout(Context context,
AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public PaperPlaneLayout(Context context,
AttributeSet attrs,int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init() {
// Initialize the displayed picture
drawables = new Drawable[4];
Drawable pink =
getResources().getDrawable(R.drawable.pl_pink);
Drawable yellow =
getResources().getDrawable(R.drawable.pl_yellow);
Drawable green =
getResources().getDrawable(R.drawable.pl_green);
Drawable blue =
getResources().getDrawable(R.drawable.pl_blue);
drawables[0] = blue;
drawables[1] = yellow;
drawables[2] = green;
drawables[3] = pink;
// Get the width and height of a graph Used for later calculations
// Attention Here I am 4 The size of each picture is 1 Like , So I just took 1 A
dHeight = UIUtility.dipTopx(getContext(), 80);
dWidth = UIUtility.dipTopx(getContext(), 80);
lp = new LayoutParams(dWidth, dHeight);
}
@Override
protected void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = getMeasuredWidth();
mHeight = getMeasuredHeight();
}
// The entrance to the real animation, which is called from the outside, x , y Respectively indicate that after the aircraft enters,
// Position coordinates of staying
public void addHeart(int x, int y, int position) {
mX = x;
mY = y;
ImageView imageView = new ImageView(getContext());
// Random selection 1 A
imageView.setImageDrawable(drawables[position]);
imageView.setLayoutParams(lp);
addView(imageView);
// Get animation before and after entering
Animator set = getAnimator(imageView);
set.start();
imageView.setOnClickListener(this);
}
private Animator getAnimator(View target) {
AnimatorSet set = getEnterAnimator(target);
AnimatorSet set2 = getLineAnimation(target);
AnimatorSet finalSet = new AnimatorSet();
finalSet.playSequentially(set, set2);
finalSet.setInterpolator(new LinearInterpolator());
finalSet.setTarget(target);
return finalSet;
}
private AnimatorSet getEnterAnimator(final View target) {
ObjectAnimator alpha = ObjectAnimator
.ofFloat(target, View.ALPHA, 0.2f, 1f);
ObjectAnimator translationX = ObjectAnimator
.ofFloat(target, View.TRANSLATION_X,
-2 * mWidth, -mWidth);
AnimatorSet enter = new AnimatorSet();
enter.setDuration(500);
enter.setInterpolator(new LinearInterpolator());
enter.playTogether(translationX, alpha);
enter.setTarget(target);
return enter;
}
private AnimatorSet getLineAnimation(final View iconView) {
ObjectAnimator transX = ObjectAnimator
.ofFloat(iconView, "translationX", -dWidth, mX);
ObjectAnimator transY = ObjectAnimator
.ofFloat(iconView, "translationY",
(mHeight - dHeight) / 2, mY);
transY.
setInterpolator(PathInterpolatorCompat
.create(0.7f, 1f));
AnimatorSet flyUpAnim = new AnimatorSet();
flyUpAnim.setDuration(900);
flyUpAnim.playTogether(transX, transY);
flyUpAnim.setTarget(iconView);
return flyUpAnim;
}
@Override
public void onClick(View v) {
if (mOnClickListener != null) {
mOnClickListener.onClick((ImageView) v);
}
}
// Definition ImageView Click event
public interface OnClickListener {
void onClick(ImageView v);
}
2. The next step is to build the layout file (only select 1 part of the control)
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relative_plane_bj"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/paper_plane_bg">
<!-- White clouds -->
<ImageView
android:id="@+id/img_white_cloud"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/paper_plane_cloud"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp" />
<!-- Custom Aircraft Layout Animation -->
<com.cloudi.forum.view.PaperPlaneLayout
android:id="@+id/plane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
3. Now you can use it in Activity:
public class PlaneActivity extends AppCompatActivity{
@Bind(R.id.img_white_cloud)
ImageView mImgWhiteCloud;
@Bind(R.id.plane_layout)
PaperPlaneLayout mPlaneLayout;
private Context mContext;
private ObjectAnimator objCloudAnim;
private TranslateAnimation planeAnimation;
private float iconX, iconY;
// Set whether the aircraft has been clicked, if yes true , then another 1 Planes are not clickable
private boolean mIsClick = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_plane_layout);
ButterKnife.bind(this);
mContext = getApplicationContext();
// Initialize animation
initAnimation();
initListener();
}
private void initAnimation() {
// Set the entry position of the paper airplane
initPlaneEnterAnimation();
// The plane floats up and down after entering
initPlaneAnimation();
// Clouds circulate from the right side of the screen to the left side of the screen
initCloudAnimation();
}
// Set the entry position of the paper airplane
private void initPlaneEnterAnimation() {
for (int i = 0; i < 4; i++) {
final int temp = i;
mPlaneLayout.post(new Runnable() {
@Override
public void run() {
// The following values are set by the user himself
if (temp == 0) {
mPlaneLayout.addHeart(
100dp, 140dp, 0);
}
if (temp == 1) {
mPlaneLayout.addHeart(
Screen width - 120dp, 190dp, 1);
}
if (temp == 2) {
mPlaneLayout.addHeart(
30dp, 240dp, 2);
}
if (temp == 3) {
mPlaneLayout.addHeart(
Screen width - 210, 290, 3);
}
}
});
}
}
// The plane floats up and down after entering
private void initPlaneAnimation() {
planeAnimation = new TranslateAnimation(0, 0, -10, 10);
planeAnimation.setDuration(1000);
planeAnimation.setRepeatCount(Animation.INFINITE);
planeAnimation.setRepeatMode(Animation.REVERSE);
mPlaneLayout.setAnimation(planeAnimation);
planeAnimation.start();
}
// Clouds circulate from the right side of the screen to the left side of the screen
private void initCloudAnimation() {
if (objCloudAnim == null) {
objCloudAnim = ObjectAnimator
.ofFloat(mImgWhiteCloud, "translationX",
Screen width - 50, - Screen width );
// Set duration
objCloudAnim.setDuration(5000);
// Set up loop playback
objCloudAnim.setRepeatCount(
ObjectAnimator.INFINITE);
}
objCloudAnim.start();
}
private void initListener() {
mPlaneLayout.setOnClickListener(new
PaperPlaneLayout.OnClickListener() {
@Override
public void onClick(ImageView v) {
if (mIsClick) {
mIsClick = false;
iconX = v.getX();
iconY = v.getY();
// When clicking on a 1 When there is a paper plane, the plane will have 1 Flying out animation
planeOutAnimation(v);
}
}
});
}
/**
* Airplane flying out animation
*/
private void planeOutAnimation(final View iconView) {
AnimatorSet flyUpAnim = new AnimatorSet();
flyUpAnim.setDuration(600);
ObjectAnimator transX = ObjectAnimator
.ofFloat(iconView, "translationX",
iconView.getX(),
UIUtility.getScreenWidth(mContext) * 2);
ObjectAnimator transY = ObjectAnimator
.ofFloat(iconView, "translationY",
0,
- UIUtility.getScreenHeight(mContext) * 2);
transY.setInterpolator(PathInterpolatorCompat
.create(0.7f, 1f));
ObjectAnimator rotation = ObjectAnimator
.ofFloat(iconView, "rotation", -45, 0);
rotation.setInterpolator(new DecelerateInterpolator());
ObjectAnimator rotationX = ObjectAnimator
.ofFloat(iconView, "rotationX", 0, 60);
rotationX.setInterpolator(
new DecelerateInterpolator());
flyUpAnim.playTogether(transX, transY, rotationX,
ObjectAnimator
.ofFloat(iconView, "scaleX", 1, 0.5f),
ObjectAnimator
.ofFloat(iconView, "scaleY", 1, 0.5f),
rotation
);
flyUpAnim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
// Airplane flying in animation
downPlaneAnimation(iconView);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
flyUpAnim.start();
}
/**
* Airplane flying in animation
*/
private void downPlaneAnimation(final View iconView) {
final int offDistX = -iconView.getRight();
final int offDistY = -UIUtility.dipTopx(mContext, 10);
AnimatorSet flyDownAnim = new AnimatorSet();
flyDownAnim.setDuration(500);
ObjectAnimator transX1 = ObjectAnimator
.ofFloat(iconView, "translationX",
UIUtility.getScreenWidth(mContext), offDistX);
ObjectAnimator transY1 = ObjectAnimator
.ofFloat(iconView, "translationY",
- UIUtility.getScreenHeight(mContext),
offDistY);
transY1.setInterpolator(
PathInterpolatorCompat.create(0.1f, 1f));
ObjectAnimator rotation1 = ObjectAnimator
.ofFloat(iconView, "rotation",
iconView.getRotation(), 0);
rotation1.setInterpolator(
new AccelerateInterpolator());
flyDownAnim.playTogether(transX1, transY1,
ObjectAnimator
.ofFloat(iconView, "scaleX", 0.5f, 0.9f),
ObjectAnimator
.ofFloat(iconView, "scaleY", 0.5f, 0.9f),
rotation1
);
flyDownAnim.addListener(
new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
iconView.setRotationY(180);
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
AnimatorSet flyInAnim = new AnimatorSet();
flyInAnim.setDuration(500);
flyInAnim.setInterpolator(
new DecelerateInterpolator());
ObjectAnimator tranX2 = ObjectAnimator
.ofFloat(iconView, "translationX",
offDistX, iconX);
ObjectAnimator tranY2 = ObjectAnimator
.ofFloat(iconView, "translationY",
offDistY, iconY);
ObjectAnimator rotationX2 = ObjectAnimator
.ofFloat(iconView, "rotationX", 30, 0);
flyInAnim.playTogether(tranX2, tranY2, rotationX2,
ObjectAnimator.ofFloat(iconView, "scaleX", 0.9f, 1f),
ObjectAnimator.ofFloat(iconView, "scaleY", 0.9f, 1f));
flyInAnim.setStartDelay(100);
flyInAnim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
iconView.setRotationY(0);
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
AnimatorSet mFlyAnimator = new AnimatorSet();
mFlyAnimator.playSequentially(flyDownAnim, flyInAnim);
mFlyAnimator.start();
}
In this way, the entry and exit animation of paper airplane is completed.