Android实战教程第十篇仿腾讯手机助手小火箭发射效果

之前对系统自带的土司的源码做了简要分析,见博客:点击打开链接

这一篇给一个小案例,自定义土司,模拟腾讯卫士的小火箭发射。如果想要迅速看懂代码,建议先去看一下上篇介绍点击打开链接

首先,定义一个服务,在这个服务里面,完成土司的创建(小火箭布局创建),烟的效果属于动画播放,而且要依托一个activity。(这个activity要定义为透明状态)

定义烟的activity的布局文件

<?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/smoke_m"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:layout_alignParentBottom="true"
  android:src="@drawable/desktop_smoke_m" /> 

 <ImageView
  android:layout_above="@id/smoke_m"
  android:id="@+id/smoke_t"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:src="@drawable/desktop_smoke_t"/> 

</RelativeLayout>

在对应的Smokeactivity里面加入“烟”的动画

package com.itydl.rockets; 

import android.app.Activity;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.ScaleAnimation;
import android.widget.ImageView; 

public class SmokeActivity extends Activity {
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  super.onCreate(savedInstanceState);
  setContentView(R.layout.smoke);
  //底部烟图片
  ImageView iv_m = (ImageView) findViewById(R.id.smoke_m);
  //烟柱子
  ImageView iv_t = (ImageView) findViewById(R.id.smoke_t); 

  //渐变动画
  AlphaAnimation aa = new AlphaAnimation(0.0f,1.0f);
  aa.setDuration(1000);
  //比例动画                 设置锚点。x轴一半,y轴图片最低端y值最大处
  ScaleAnimation sa = new ScaleAnimation(1.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 1f);
  sa.setDuration(1000); 

  //动画集添加动画
    iv_m.startAnimation(aa);//给下面这张图片实现渐变动画 

    AnimationSet as = new AnimationSet(true);
  as.addAnimation(aa);
  as.addAnimation(sa);
  //给上边图片(烟柱子)设置渐变动画和比例动画
  iv_t.startAnimation(as); 

  //1秒后关闭Activity,正好动画播完,关闭这个activity。这里也是那样,主线程动画的同时,子线程也在执行耗时操作
  new Thread(){
   public void run() {
    //1秒后关闭当前Activity
    SystemClock.sleep(1000);
    runOnUiThread(new Runnable() {//activity类中的方法 

     @Override
     public void run() {
      // TODO Auto-generated method stub
      finish();//关闭自己也属于更新界面操作,因此要在主线程执行。
     }
    }); 

   };
  }.start(); 

 }
}

定义Service,用于自定义土司布局,加入火箭图片的动画、参数初始化、触摸事件等

package com.itydl.rockets; 

import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.graphics.drawable.AnimationDrawable;
import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
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; 

public class RocketService extends Service { 

 private WindowManager.LayoutParams params;
 private View view;
 private WindowManager wm; 

 @Override
 public IBinder onBind(Intent intent) {
  // TODO Auto-generated method stub
  return null;
 } 

 @Override
 public void onCreate() { 

  wm = (WindowManager) getSystemService(WINDOW_SERVICE); 

  //初始化params(土司参数)
  initToastParams(); 

  showRocket();//打开小火箭
  super.onCreate();
 }
 /**
  * 初始化土司的参数
  */
 private void initToastParams() {
  // TODO Auto-generated method stub
  // XXX This should be changed to use a Dialog, with a Theme.Toast
  // defined that sets up the layout params appropriately. 

  params = new WindowManager.LayoutParams();
  params.height = WindowManager.LayoutParams.WRAP_CONTENT;
  params.width = WindowManager.LayoutParams.WRAP_CONTENT; 

  //对齐方式左上角
  params.gravity = Gravity.LEFT | Gravity.TOP;
  params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
  /* | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE */
  | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
  params.format = PixelFormat.TRANSLUCENT; 

  params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;// 土司天生不响应事件,改变类型。TYPE_SYSTEM_ALERT系统弹窗
  params.setTitle("Toast");
 } 

 private void closeRocket(){
  if (view != null) {
   wm.removeView(view);//移除小火箭
  }
 } 

 private Handler handler = new Handler(){
  public void handleMessage(android.os.Message msg) {
   wm.updateViewLayout(view, params);//更新小火箭在屏幕中的位置,刷新位置。属于更新ui。在主线程执行(更新土司的位置)
  };
 }; 

 private void showRocket(){
  //小火箭的布局 

  view = View.inflate(getApplicationContext(), R.layout.rocket, null);
  ImageView iv_rocket = (ImageView) view.findViewById(R.id.iv_rocket);
  //获取小火箭的动画背景
  AnimationDrawable ad = (AnimationDrawable) iv_rocket.getBackground();
  //开始小火箭动画(小火箭动画,两张图片切换)
  ad.start(); 

  //给小火箭加触摸事件(给自定义土司加触摸事件),按住拖动小火箭到屏幕正下方,松开发射火箭
  view.setOnTouchListener(new OnTouchListener() { 

   private float startX;
   private float startY; 

   @Override
   public boolean onTouch(View v, MotionEvent event) {
    System.out.println(event.getX() + ":" + event.getRawX());
    // 拖动土司
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:// 按下
     startX = event.getRawX();
     startY = event.getRawY();
     break;
    case MotionEvent.ACTION_MOVE:// 按下移动,拖动
     //新的 x y坐标
     float moveX = event.getRawX();//移动后的x坐标
     float moveY = event.getRawY();//移动后的y坐标 

     //dx x方向的位置变化值 dy y方向的位置变化值
     float dx = moveX - startX;
     float dy = moveY - startY;
     //改变土司的坐标
     params.x += dx;
     params.y += dy;
     //重新获取新的x y坐标
     startX = moveX;
     startY = moveY; 

     //更新土司的位置
     wm.updateViewLayout(view, params);
     break;
    case MotionEvent.ACTION_UP:// 松开,接下来要发射小火箭
     //判断位置 发射
     //x轴方向 离两边框超过100,y轴方向大于200 就可以发射火箭
     if (params.x > 100 && params.x + view.getWidth()< wm.getDefaultDisplay().getWidth() - 100 &&
       params.y > 200){
      //发射火箭
      //1,火箭往上跑
      //火箭在中心线上发射(自定义土司左上角为基准)
      params.x = (wm.getDefaultDisplay().getWidth() - view.getWidth()) / 2; 

      new Thread(){//发射火箭改变y轴属于耗时操作,更新火箭位置是更新UI操作
       public void run() {
        for (int j = 0; j < view.getHeight(); ) {
         SystemClock.sleep(50);//休眠50毫秒
         params.y -= j;
         j += 5;
         handler.obtainMessage().sendToTarget();//参数y的值改变一次,发消息通知更新一次ui,更新一次土司的位置
        } 

        //,发射完毕,关闭小火箭
        stopSelf();//关闭服务,关闭当前自己服务。这个方法用在关闭自己服务里。触发onDestroy方法,从而触发这个方法里面的关闭小火箭
       };
      }.start(); 

      //2,烟的效果。因为更新火箭往上跑是在子线程执行的,因此在小火箭往上跑的同时,烟的效果也同时开始播放(子线程不影响主线程执行。两个线程可以同时进行)
      //烟的效果,是一个动画,在activity完成,这个activity需要定义为透明
      Intent intent = new Intent(RocketService.this,SmokeActivity.class);
      //在服务中打开activity,需要设置任务栈:
      intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//任务栈
      startActivity(intent);//启动烟的Activity
     }
     //冒烟的Activity
    default:
     break;
    }
    return false;//默认返回值。
   }
  }); 

  wm.addView(view, params);//把小火箭加到窗体管理器
 } 

 @Override
 public void onDestroy() {
  // TODO Auto-generated method stub
  closeRocket();//关闭小火箭
  super.onDestroy();
 } 

}

对于主动人任务只是加入个按钮,打开这个服务就行了。

package com.itydl.rockets; 

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View; 

public class MainActivity extends Activity { 

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main); 

 } 

 /**
  * 通过点击按钮打开小火箭
  * @param v
  */
 public void openRocket(View v){
  //RocketService service = new RocketService();
  Intent service = new Intent(this,RocketService.class);
  startService(service);//启动小火箭服务
  finish();//关闭当前界面。因为要显示火箭发射,不能在这个activity里面演示
 } 

}

最后清单文件配置上两个活动和一个服务,还有一个弹出窗体的权限

<activity
   android:name="com.itheima62.rockets.MainActivity"
   android:label="@string/app_name" >
   <intent-filter>
    <action android:name="android.intent.action.MAIN" /> 

    <category android:name="android.intent.category.LAUNCHER" />
   </intent-filter>
  </activity>
  <!-- 配置该活动的主题,为透明、无标题、全屏 -->
  <activity android:name="com.itheima62.rockets.SmokeActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"></activity>
  <service android:name="com.itheima62.rockets.RocketService"></service>

代码如下:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

好了主要代码和功能都介绍完了,看一下运行效果截图:

完整代码请查看文末的原文链接。

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

(0)

相关推荐

  • Android实现桌面悬浮小火箭效果

    本文实例为大家分享了Android实现悬浮小火箭效果的具体代码,供大家参考,具体内容如下 思路 使用serivce在后台启动小火箭 小火箭使用windowmanager实现. 用ontoch监听实现小火箭的拖拽. 代码实现 public class RocketService extends Service { private WindowManager mWM; private View view; private int startX ; private int startY ; priva

  • Android实战教程第十篇仿腾讯手机助手小火箭发射效果

    之前对系统自带的土司的源码做了简要分析,见博客:点击打开链接 这一篇给一个小案例,自定义土司,模拟腾讯卫士的小火箭发射.如果想要迅速看懂代码,建议先去看一下上篇介绍点击打开链接 首先,定义一个服务,在这个服务里面,完成土司的创建(小火箭布局创建),烟的效果属于动画播放,而且要依托一个activity.(这个activity要定义为透明状态) 定义烟的activity的布局文件 <?xml version="1.0" encoding="utf-8"?>

  • Android实战教程第八篇之短信备份

    各种手机助手里面都包含了短信备份这一项.短信的本分主要包含四项:内容body.事件date.方式type.号码address. 短信备份~一.使用一种很笨的方式来保存短信到xml文件中,而且保存在外部存储.后续会有:短信备份~二(xml序列化器):短信备份~三(内容提供者获取短信xml备份):短信备份~四(json方式备份数据库短信).备份的方式越来越高效,比较不同存储方式. 很显然,初次介绍短信备份,以一种简单笨拙的方式,且不涉及内容提供者,虚拟10条短信. 短信的保存,要以对象的形式保存.因

  • Android实战教程第六篇之一键锁屏应用问题解决

    上一篇,初步开发了这个应用,功能都有了(见http://www.jb51.net/article/96992.htm 点击打开链接). 但是遗留了两个问题:1.还是无法卸载:2.必须手动去点击应用程序进入程序,再点击按钮,这显得很麻烦. 这一篇就解决上面两个问题,做出最好的效果. 首先解决无法卸载问题: 在清单文件中,再配置一键卸载的主活动(两个主活动无所谓,只不过在桌面上显示两个图标而已,其实仍然是一个应用) <activity android:name="com.itydl.locks

  • Android实战教程第四篇之简单实现短信发送器

    本文实例为大家分享了Android发短信功能的实现方法,供大家参考,具体内容如下 首先配置一个布局: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_

  • Android实战教程第五篇之一键锁屏应用

    Device Administration 对于这个应用,市场上很多,但是看一下评论就知道效果有多差了,因为99%一键锁屏应用没办法卸载.今天就开发一个小应用,实现轻松点击一键锁屏,同时支持卸载... 通查看谷歌原文档,有设备管理器的API,从这里可以抽取一些代码,开发出一个小应用,即即将介绍的<一键锁屏>. 根据文档翻译,获取设备管理器的大致步骤如下: 1.创建类DeviceAdminReceiver的子类 如:com.itydl.lockscreen.DeviceAdminSample 2

  • Android实战教程第七篇之如何在内存中存储用户名和密码

    本文实例为大家分享了Android内存中存储用户名和密码的方法,供大家参考,具体内容如下 首先是配置文件: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layo

  • Android实战教程第三篇之简单实现拨打电话功能

    本文实例为大家分享了Android打电话功能的实现代码,需要一个文本输入框输入号码,需要一个按钮打电话. 本质:点击按钮,调用系统打电话功能. xml布局文件代码:: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="m

  • JS实现仿腾讯微博无刷新删除微博效果代码

    本文实例讲述了JS实现仿腾讯微博无刷新删除微博效果代码.分享给大家供大家参考.具体如下: 这里演示JS仿腾讯微博无刷新删除效果,将显示在微博列表里的内容删除,运用AJAX技术,无刷新删除微博的内容,参考性强,希望对初学AJAX的朋友有所帮助. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/js-f-sina-web-ajax-del-info-demo/ 具体代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD

  • Android实战教程第四十篇之Chronometer实现倒计时

    Android提供了实现按照秒计时的API,今天就是用这个API实现简单的倒计时. 来个布局: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:lay

  • Android实战教程第一篇之最简单的计算器

    从今天开始,本专栏持续更新Android简易实战类博客文章.和以往专栏不同,此专栏只有实例.每个实例尽量按照知识点对应相应一章节的内容去写,循序渐进.有些实例可能会与另一个专栏有重复的文章. 开始本专栏的第一个简易案例: 首先设置两个布局文件,一个布局文件进行输入数据,获取加法运算:另一个布局文件进行显示最终结果.Activity1启动Activity2,并传递计算结果值给Activity2. main.xml: <?xml version="1.0" encoding=&quo

随机推荐