android仿腾讯小火箭案例

效果展示

效果图如下

思路分析
  • 首先要准备两张小火箭图片,通过帧动画来实现火箭喷火的效果
  • 准备两张看似冒白烟的图片,在火箭的发射的时候通过渐变动画实现发射时的效果
  • 熟悉view的onTouch事件处理,以及android基本动画的使用
  • 当小火箭被拖动到发射区域时抬起时火箭发射,执行冒白烟的渐变动画,当火箭飞出屏幕时结束所有动画
具体实现步骤

一、在res/drawable目录下创建一个帧动画的xml文件,desktop_rocket_launch_1和desktop_rocket_launch_1分别是两张不同的小火箭状态的图片

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/selected"
    android:oneshot="false" >

    <item
        android:drawable="@drawable/desktop_rocket_launch_1"
        android:duration="50"/>
    <item
        android:drawable="@drawable/desktop_rocket_launch_2"
        android:duration="50"/>

</animation-list>

二、在java文件中通过下面代码的实现小火箭的喷火效果

    mImgAnim.setBackgroundResource(R.drawable.desktop_rocket_launch);
        AnimationDrawable frameAnimation = (AnimationDrawable) mImgAnim
                .getBackground();
        frameAnimation.start();

三、触摸小火箭时随手指移动

mImgAnim.setOnTouchListener(new OnTouchListener() {
            private int startX;
            private int startY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    startX = (int) event.getRawX();
                    startY = (int) event.getRawY();
                    System.out.println("按下");
                    break;
                case MotionEvent.ACTION_MOVE:
                    System.out.println("移动");
                    // 获取移动后的位置
                    int moveX = (int) event.getRawX();
                    int moveY = (int) event.getRawY();
                    // 计算偏移量
                    int vX = moveX - startX;
                    int vY = moveY - startY;
                    // 获取没有重绘前view离屏幕左边和上边的距离
                    int l = mImgAnim.getLeft();
                    int t = mImgAnim.getTop();
                    l += vX;
                    t += vY;
                    // 边界值处理
                    l = l < 0 ? 0
                            : (l > mScreeWidth - mImgAnim.getWidth() ? mScreeWidth
                                    - mImgAnim.getWidth()
                                    : l);
                    t = t < 0 ? 0
                            : (t > mScreeHeight - mImgAnim.getHeight() ? mScreeHeight
                                    - mImgAnim.getHeight()
                                    : t);
                    // r和b受到l和t的影响,所以不用做处理
                    int r = l + mImgAnim.getWidth();
                    int b = t + mImgAnim.getHeight();
                    // 重绘view
                    mImgAnim.layout(l, t, r, b);
                    // 修改起点坐标
                    startX = moveX;
                    startY = moveY;
                    break;
                case MotionEvent.ACTION_UP:

                    int width = mImgAnim.getWidth();
                    // 发射火箭
                    // 判断是否在指定的位置
                    if (mImgAnim.getLeft() > mScreeWidth / 2 - width
                            && mImgAnim.getLeft() < mScreeWidth / 2 + width
                            && mImgAnim.getTop() > mScreeHeight
                                    - mImgAnim.getHeight() - 20) {
                        System.out.println("发射火箭");
                        sendRocket();
                        mSmoke.startAnimation(alphaAnimation);
                        mSmoke_t.startAnimation(alphaAnimation);
                    }
                    break;

                }
                return true;
            }
        });

四、当手指抬起时如果火箭位于发射位置,则发射火箭,同时取消所有动画


        new Thread() {
            public void run() {

                do {
                    SystemClock.sleep(10);
                    // 运行在ui线程操作
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            // 减小控件距离屏幕顶部的距离
                            int top = mImgAnim.getTop() - 8;
                            // 重新绘制控件
                            mImgAnim.layout(mImgAnim.getLeft(), top,
                                    mImgAnim.getLeft() + mImgAnim.getWidth(),
                                    top + mImgAnim.getHeight());
                            System.out.println("top=" + top);
                        }
                    });

                } while (mImgAnim.getBottom() > 0);
                // 关闭动画
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        mSmoke.clearAnimation();
                        mSmoke_t.clearAnimation();
                    }
                });
            };
        }.start();
完整代码如下,布局自定义

/**
 * @author rongtao
 *  小火箭案例
 */
public class MainActivity extends Activity {

    private MainActivity mContext;
    private ImageView mImgAnim;
    private ImageView mSmoke;
    private int mScreeWidth;
    private int mScreeHeight;
    private AlphaAnimation alphaAnimation;
    private ImageView mSmoke_t;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = this;
        getScreenInfo();
        init();
    }

    /**
     * 获取屏幕宽高
     */
    private void getScreenInfo() {
        // 获取手机屏幕信息
        DisplayMetrics outMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
        ;
        mScreeWidth = outMetrics.widthPixels;
        mScreeHeight = outMetrics.heightPixels;
    }

    private void init() {
        mImgAnim = (ImageView) findViewById(R.id.img_anim);
        mSmoke = (ImageView) findViewById(R.id.img_smoke);
        mSmoke_t = (ImageView) findViewById(R.id.img_smoke_t);
        loadAnimation();
        touchRocket();
    }

    private void loadAnimation() {
        mImgAnim.setBackgroundResource(R.drawable.desktop_rocket_launch);
        AnimationDrawable frameAnimation = (AnimationDrawable) mImgAnim
                .getBackground();
        frameAnimation.start();
        alphaAnimation = new AlphaAnimation(0, 1.0f);// 初始化渐变动画
        alphaAnimation.setDuration(2000);
    }

    private void touchRocket() {

        mImgAnim.setOnTouchListener(new OnTouchListener() {
            private int startX;
            private int startY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    startX = (int) event.getRawX();
                    startY = (int) event.getRawY();
                    System.out.println("按下");
                    break;
                case MotionEvent.ACTION_MOVE:
                    System.out.println("移动");
                    // 获取移动后的位置
                    int moveX = (int) event.getRawX();
                    int moveY = (int) event.getRawY();
                    // 计算偏移量
                    int vX = moveX - startX;
                    int vY = moveY - startY;
                    // 获取没有重绘前view离屏幕左边和上边的距离
                    int l = mImgAnim.getLeft();
                    int t = mImgAnim.getTop();
                    l += vX;
                    t += vY;
                    // 边界值处理
                    l = l < 0 ? 0
                            : (l > mScreeWidth - mImgAnim.getWidth() ? mScreeWidth
                                    - mImgAnim.getWidth()
                                    : l);
                    t = t < 0 ? 0
                            : (t > mScreeHeight - mImgAnim.getHeight() ? mScreeHeight
                                    - mImgAnim.getHeight()
                                    : t);
                    // r和b受到l和t的影响,所以不用做处理
                    int r = l + mImgAnim.getWidth();
                    int b = t + mImgAnim.getHeight();
                    // 重绘view
                    mImgAnim.layout(l, t, r, b);
                    // 修改起点坐标
                    startX = moveX;
                    startY = moveY;
                    break;
                case MotionEvent.ACTION_UP:

                    int width = mImgAnim.getWidth();
                    // 发射火箭
                    // 判断是否在指定的位置
                    if (mImgAnim.getLeft() > mScreeWidth / 2 - width
                            && mImgAnim.getLeft() < mScreeWidth / 2 + width
                            && mImgAnim.getTop() > mScreeHeight
                                    - mImgAnim.getHeight() - 20) {
                        System.out.println("发射火箭");
                        sendRocket();
                        mSmoke.startAnimation(alphaAnimation);
                        mSmoke_t.startAnimation(alphaAnimation);
                    }
                    break;

                }
                return true;
            }
        });
    }

    /**
     * 发送火箭效果
     * 
     * 通过减少Top值得方法实现火箭的发射
     */
    protected void sendRocket() {

        new Thread() {
            public void run() {

                do {
                    SystemClock.sleep(10);
                    // 运行在ui线程操作
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            // 减小控件距离屏幕顶部的距离
                            int top = mImgAnim.getTop() - 8;
                            // 重新绘制控件
                            mImgAnim.layout(mImgAnim.getLeft(), top,
                                    mImgAnim.getLeft() + mImgAnim.getWidth(),
                                    top + mImgAnim.getHeight());
                            System.out.println("top=" + top);
                        }
                    });

                } while (mImgAnim.getBottom() > 0);
                // 关闭动画
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        mSmoke.clearAnimation();
                        mSmoke_t.clearAnimation();
                    }
                });
            };
        }.start();
    }
}

发射火箭可以通过其他的方式实现,有兴趣的自己研究。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值