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,不如许别的进来.

 


本文转自农夫山泉别墅博客园博客,原文链接:http://www.cnblogs.com/yaowen/p/5128947.html,如需转载请自行联系原作者

相关文章
|
开发工具 Android开发
Android零基础入门第14节:使用高速Genymotion,跨入火箭时代
原文:Android零基础入门第14节:使用高速Genymotion,跨入火箭时代 无论是使用Eclipse,还是Android Studio,使用自带的Android模拟器,不仅很费电脑内存,模拟器开机和运行程序的速度很慢,严重影响开发效率。
1625 0
|
25天前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
28天前
|
缓存 前端开发 Android开发
安卓开发中的自定义视图:从零到英雄
【10月更文挑战第42天】 在安卓的世界里,自定义视图是一块画布,让开发者能够绘制出独一无二的界面体验。本文将带你走进自定义视图的大门,通过深入浅出的方式,让你从零基础到能够独立设计并实现复杂的自定义组件。我们将探索自定义视图的核心概念、实现步骤,以及如何优化你的视图以提高性能和兼容性。准备好了吗?让我们开始这段创造性的旅程吧!
23 1
|
1月前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
12天前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
39 19
|
25天前
|
IDE Java 开发工具
移动应用与系统:探索Android开发之旅
在这篇文章中,我们将深入探讨Android开发的各个方面,从基础知识到高级技术。我们将通过代码示例和案例分析,帮助读者更好地理解和掌握Android开发。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。让我们一起开启Android开发的旅程吧!
|
13天前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
38 14
|
16天前
|
Java Linux 数据库
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。
|
14天前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
在数字时代,掌握安卓应用开发技能是进入IT行业的关键。本文将引导读者从零基础开始,逐步深入安卓开发的世界,通过实际案例和代码示例,展示如何构建自己的第一个安卓应用。我们将探讨基本概念、开发工具设置、用户界面设计、数据处理以及发布应用的全过程。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你提供宝贵的知识和技能,帮助你在安卓开发的道路上迈出坚实的步伐。
27 5
|
12天前
|
开发框架 Android开发 iOS开发
安卓与iOS开发中的跨平台策略:一次编码,多平台部署
在移动应用开发的广阔天地中,安卓和iOS两大阵营各占一方。随着技术的发展,跨平台开发框架应运而生,它们承诺着“一次编码,到处运行”的便捷。本文将深入探讨跨平台开发的现状、挑战以及未来趋势,同时通过代码示例揭示跨平台工具的实际运用。