zoukankan      html  css  js  c++  java
  • android138 360 小火箭

    package com.itheima52.rocket;
    
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.graphics.PixelFormat;
    import android.graphics.drawable.AnimationDrawable;
    import android.os.Handler;
    import android.os.IBinder;
    import android.os.Message;
    import android.view.Gravity;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.View.OnTouchListener;
    import android.view.WindowManager;
    import android.widget.ImageView;
    
    /*
     * 主界面开启一个服务
        startService(new Intent(this, RocketService.class));
        finish();
        stopService(new Intent(this, RocketService.class));
        finish();
    */
    public class RocketService extends Service {
    
        private WindowManager.LayoutParams params;
        private int winWidth;
        private int winHeight;
        private WindowManager mWM;
        private View view;
    
        private int startX;
        private int startY;
    
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            mWM = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);//WindowManager可以在手机屏幕上显示,而不用依赖于某个activity布局文件。
    
            // 获取屏幕宽高
            winWidth = mWM.getDefaultDisplay().getWidth();
            winHeight = mWM.getDefaultDisplay().getHeight();
    
            params = new WindowManager.LayoutParams();
            params.height = WindowManager.LayoutParams.WRAP_CONTENT;
            params.width = WindowManager.LayoutParams.WRAP_CONTENT;
            params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
            params.format = PixelFormat.TRANSLUCENT;
            params.type = WindowManager.LayoutParams.TYPE_PHONE;// 电话窗口。它用于电话交互(特别是呼入)。它置于所有应用程序之上,状态栏之下。
            params.gravity = Gravity.LEFT + Gravity.TOP;// 将重心位置设置为左上方,
                                                        // 也就是(0,0)从左上方开始,而不是默认的重心位置
            params.setTitle("Toast");
    
            view = View.inflate(this, R.layout.rocket, null);// 初始化火箭布局
    
            // 初始化火箭帧动画
            ImageView ivRocket = (ImageView) view.findViewById(R.id.iv_rocket);
            /*iv_rocket.xml
            <?xml version="1.0" encoding="utf-8"?>
            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical" >
                <ImageView
                    android:id="@+id/iv_rocket"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/desktop_rocket_launch_1" />        火箭图片
            </LinearLayout>*/
            
            //火箭冒火帧动画,火苗一直闪烁,
            ivRocket.setBackgroundResource(R.drawable.anim_rocket);
            /*
            anim_rocket.xml
            <?xml version="1.0" encoding="utf-8"?>
            <animation-list xmlns:android="http://schemas.android.com/apk/res/android" >
              2张图片切换,200毫秒,
                <item
                    android:drawable="@drawable/desktop_rocket_launch_1"
                    android:duration="200"/>
                <item
                    android:drawable="@drawable/desktop_rocket_launch_2"
                    android:duration="200"/>
            </animation-list>
            */
            AnimationDrawable anim = (AnimationDrawable) ivRocket.getBackground();
            anim.start();
    
            mWM.addView(view, params);
    
            view.setOnTouchListener(new OnTouchListener() {
    
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        // 初始化起点坐标
                        startX = (int) event.getRawX();
                        startY = (int) event.getRawY();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        int endX = (int) event.getRawX();
                        int endY = (int) event.getRawY();
    
                        // 计算移动偏移量
                        int dx = endX - startX;
                        int dy = endY - startY;
    
                        // 更新浮窗位置,WindowManager里面只能用params来移动
                        params.x += dx;
                        params.y += dy;
    
                        // 防止坐标偏离屏幕
                        if (params.x < 0) {
                            params.x = 0;
                        }
                        if (params.y < 0) {
                            params.y = 0;
                        }
    
                        // 防止坐标偏离屏幕
                        if (params.x > winWidth - view.getWidth()) {
                            params.x = winWidth - view.getWidth();
                        }
                        if (params.y > winHeight - view.getHeight()) {
                            params.y = winHeight - view.getHeight();
                        }
                        // System.out.println("x:" + params.x + ";y:" + params.y);
                        mWM.updateViewLayout(view, params);
    
                        // 重新初始化起点坐标
                        startX = (int) event.getRawX();
                        startY = (int) event.getRawY();
                        break;
                    case MotionEvent.ACTION_UP:
                        if (params.x > 100 && params.x < 250 && params.y > winHeight - 120) {
                            System.out.println("发射火箭!!!");
                            sendRocket();
    
                            // 启动烟雾效果,启动一个Activity,盖住下面的Activity,使得下面的不能点击。
                            Intent intent = new Intent(RocketService.this,BackgroundActivity.class);
                            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);// 通过Service启动Activity,Service不用栈,因此要先启动一个栈来存放activity
                            startActivity(intent);
                        }
                        break;
    
                    default:
                        break;
                    }
                    return true;
                }
            });
        }
    
        private Handler mHandler = new Handler() {
            public void handleMessage(android.os.Message msg) {
                // 更新火箭位置
                int y = msg.arg1;
                params.y = y;
                mWM.updateViewLayout(view, params);
            };
        };
    
        /**
         * 发射火箭
         */
        protected void sendRocket() {
            // 设置火箭居中发射
            params.x = winWidth / 2 - view.getWidth() / 2;
            mWM.updateViewLayout(view, params);
    
            new Thread() {
                @Override
                public void run() {
                    int pos = 380;// 移动总距离
                    for (int i = 0; i <= 10; i++) {//移动10次,就移动到顶部了。
                        // 等待一段时间再更新位置,用于控制火箭速度
                        try {
                            Thread.sleep(50);//主线程睡眠会让主线程很卡,因此要用子线城。
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        int y = pos - 38 * i;
                        Message msg = Message.obtain();//不能在子线城更新界面
                        msg.arg1 = y;
                        mHandler.sendMessage(msg);
                    }
                }
            }.start();
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            if (mWM != null && view != null) {
                mWM.removeView(view);
                view = null;
            }
        }
    }
    package com.itheima52.rocket;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.view.animation.AlphaAnimation;
    import android.widget.ImageView;
    /**
     * 烟雾背景
     */
    public class BackgroundActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_bg);
            /*
            activity_bg.xml
            <?xml version="1.0" encoding="utf-8"?>
            <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent" >
                <ImageView
                    android:id="@+id/iv_bottom"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentBottom="true"
                    android:layout_alignParentLeft="true"
                    android:src="@drawable/desktop_smoke_m" />    底下的大烟图片
                <ImageView
                    android:id="@+id/iv_top"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_above="@+id/iv_bottom"
                    android:layout_alignParentLeft="true"
                    android:src="@drawable/desktop_smoke_t" />   中间的细长的烟
            </RelativeLayout>*/
            ImageView ivTop = (ImageView) findViewById(R.id.iv_top);
            ImageView ivBottom = (ImageView) findViewById(R.id.iv_bottom);
    
            // 渐变动画
            AlphaAnimation anim = new AlphaAnimation(0, 1);
            anim.setDuration(1000);
            anim.setFillAfter(true);// 动画结束后保持状态
    
            // 运行动画
            ivTop.startAnimation(anim);
            ivBottom.startAnimation(anim);
    
            new Handler().postDelayed(new Runnable() {//Handler可以发message也可以发Runnable
                @Override
                public void run() {
                    finish();
                }
            }, 1000);// 延时1秒后结束activity,不能直接调用finish,因为动画要执行1秒钟。
        }
    }

    activity的启动模式:
    1.Standard:启动A,然后A启动B,B再启动A。
    2.SingleTask:首先启动A,A启动B,B启动C,C启动A的时候把B,C干掉,也就是栈里面只能有一个A.
    3.SingleTop:启动A,A启动B,B启动C,C再启动C时不会创建新的C而是用原来的C,因为顶上只能有一个C.
    4.SingleInstance:只有一个A,不如许别的进来.
  • 相关阅读:
    leetcode 190 Reverse Bits
    vs2010 单文档MFC 通过加载位图文件作为客户区背景
    leetcode 198 House Robber
    记忆化搜索(DP+DFS) URAL 1183 Brackets Sequence
    逆序数2 HDOJ 1394 Minimum Inversion Number
    矩阵连乘积 ZOJ 1276 Optimal Array Multiplication Sequence
    递推DP URAL 1586 Threeprime Numbers
    递推DP URAL 1167 Bicolored Horses
    递推DP URAL 1017 Staircases
    01背包 URAL 1073 Square Country
  • 原文地址:https://www.cnblogs.com/yaowen/p/5128947.html
Copyright © 2011-2022 走看看