android 飞机动画,Android实现纸飞机的简单操作

本文详细介绍了如何在Android应用中实现纸飞机从屏幕左侧飞入并做上下浮动的动画效果,以及点击纸飞机后其飞出屏幕再重新飞回的交互动画。通过自定义RelativeLayout和使用ObjectAnimator等工具,创建了纸飞机进入、浮动、点击反馈等一系列流畅的动画效果。同时,文章还展示了云彩从右向左飘动的循环动画实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在项目中,我们要求做一个纸飞机的功能:就是当打开这个界面时,会有4架纸飞机从屏幕左侧飞入,然后到达自己的位置坐上下浮动,同时云彩也不断地从屏幕右侧飘到屏幕左侧。当你点击其中一个纸飞机时,这个纸飞机先向上飞出屏幕外,再从左侧飞入,当飞机回到原来位置时,弹出一个消息框。下面直接上代码:

一、首先自定义一个RelativeLayout,主要目的就是制作飞机的进入动画:

public class PaperPlaneLayout extends RelativeLayout implements View.OnClickListener{

private OnClickListener mOnClickListener;

//自定义布局的宽、高

private int mHeight;

private int mWidth;

private LayoutParams lp;

private Drawable[] drawables;

private Random random = new Random();

//获取4架纸飞机的宽高

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() {

// 初始化显示的图片

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;

// 获取图的宽高 用于后面的计算

// 注意 我这里4张图片的大小都是一样的,所以我只取了一个

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();

}

//真正动画开始的入口,从外部进行调用,x、y分别表示飞机进入之后所

//停留的位置坐标

public void addHeart(int x, int y, int position) {

mX = x;

mY = y;

ImageView imageView = new ImageView(getContext());

// 随机选一个

imageView.setImageDrawable(drawables[position]);

imageView.setLayoutParams(lp);

addView(imageView);

//获取进入前后动画

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);

}

}

//定义ImageView单击事件

public interface OnClickListener {

void onClick(ImageView v);

}

二、接下来就是布局文件的搭建了(只选取一部分控件)

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">

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" />

android:id="@+id/plane_layout"

android:layout_width="match_parent"

android:layout_height="match_parent"/>

三、接下来就可以在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;

//设置飞机是否已点击,如果为true,则另一个飞机不可点击

private boolean mIsClick = true;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_plane_layout);

ButterKnife.bind(this);

mContext = getApplicationContext();

//初始化动画

initAnimation();

initListener();

}

private void initAnimation() {

//设定纸飞机进入的位置

initPlaneEnterAnimation();

//飞机进入后做上下浮动

initPlaneAnimation();

//云彩循环从屏幕右侧飘到屏幕左侧

initCloudAnimation();

}

//设定纸飞机进入的位置

private void initPlaneEnterAnimation() {

for (int i = 0; i < 4; i++) {

final int temp = i;

mPlaneLayout.post(new Runnable() {

@Override

public void run() {

//下面的值根据用户自己设定

if (temp == 0) {

mPlaneLayout.addHeart(

100dp, 140dp, 0);

}

if (temp == 1) {

mPlaneLayout.addHeart(

屏宽 - 120dp, 190dp, 1);

}

if (temp == 2) {

mPlaneLayout.addHeart(

30dp, 240dp, 2);

}

if (temp == 3) {

mPlaneLayout.addHeart(

屏宽 - 210, 290, 3);

}

}

});

}

}

//飞机进入后做上下浮动

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();

}

//云彩循环从屏幕右侧飘到屏幕左侧

private void initCloudAnimation() {

if (objCloudAnim == null) {

objCloudAnim = ObjectAnimator

.ofFloat(mImgWhiteCloud, "translationX",

屏宽 - 50, -屏宽);

// 设置持续时间

objCloudAnim.setDuration(5000);

// 设置循环播放

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();

//当点击某一个纸飞机时,飞机会有一个飞出动画

planeOutAnimation(v);

}

}

});

}

/**

* 飞机飞出动画

*/

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) {

// 飞机飞入动画

downPlaneAnimation(iconView);

}

@Override

public void onAnimationCancel(Animator animation) {

}

@Override

public void onAnimationRepeat(Animator animation) {

}

});

flyUpAnim.start();

}

/**

* 飞机飞入动画

*/

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();

}

这样一来纸飞机的进入和点击离开动画就完成了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值