android 悬浮窗口

来源:互联网 发布:心电监护仪怎么看数据 编辑:程序博客网 时间:2024/04/30 19:37
本帖最后由 锋翼 于 2012-1-9 22:01 编辑

不知道有没有童鞋用过QQ的Android版本中的一个高清版本,当你退出QQ的时候,会在你的屏幕上出现一个QQ图标的悬浮窗,就和PC上的迅雷的悬浮窗口一样,在所有应用的最上层,本来这个功能感觉还是挺好的,结果TX就给流氓了下,居然没有做隐藏掉这个悬浮窗的功能。

今天就来为大家简单介绍下这个悬浮窗的实现方法吧,不过记住至少还是给用户做一个隐藏掉这个悬浮窗的功能吧!其实实现原理还是挺简单的,就是利用WindowManager将你的图标View添加到窗口中,不知道大家知道WindowManager.LayoutParams中有一个type属性不,这里玄机挺大的,找了好久,终于给我试出来有一个TYPE_PHONE可以来实现这个功能的,该类型提供与用户交互,置于所有应用程序上方,但是在状态栏后面。至于其他的类型,大家还是去找API或者GG吧。
先看下效果图吧:
device-2012-01-09-213745.png
红框圈中得图标可以任意拖动哦,你可以根据自己的实际需要给图标添加功能。

核心代码如下:
  1. package com.apkstory.service;

  2. import com.apkstory.R;
  3. import com.apkstory.util.MyApplication;

  4. import android.app.Service;
  5. import android.content.Intent;
  6. import android.graphics.PixelFormat;
  7. import android.os.IBinder;
  8. import android.view.Gravity;
  9. import android.view.LayoutInflater;
  10. import android.view.MotionEvent;
  11. import android.view.View;
  12. import android.view.WindowManager;
  13. import android.view.View.OnTouchListener;

  14. /**
  15. * 悬浮窗的制作
  16. * @author 锋翼
  17. * @link www.apkstory.com
  18. */
  19. public class TopFloatService extends Service {

  20.         WindowManager wm = null;
  21.         WindowManager.LayoutParams wmParams = null;
  22.         View view;
  23.         private float mTouchStartX;
  24.         private float mTouchStartY;
  25.         private float x;
  26.         private float y;
  27.        
  28.         @Override
  29.         public void onCreate() {
  30.                 super.onCreate();
  31.                 view = LayoutInflater.from(this).inflate(R.layout.floating, null);
  32.                 createView();
  33.         }

  34.         private void createView() {
  35.                 // 获取WindowManager
  36.                 wm = (WindowManager) getApplicationContext().getSystemService("window");
  37.                 // 设置LayoutParams(全局变量)相关参数
  38.                 wmParams =  ((MyApplication) getApplication()).getMywmParams();
  39.                 wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;// 该类型提供与用户交互,置于所有应用程序上方,但是在状态栏后面
  40.                 wmParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;// 不接受任何按键事件
  41.                 wmParams.gravity = Gravity.LEFT | Gravity.TOP; // 调整悬浮窗口至左上角
  42.                 // 以屏幕左上角为原点,设置x、y初始值
  43.                 wmParams.x = 0;
  44.                 wmParams.y = 0;
  45.                 // 设置悬浮窗口长宽数据
  46.                 wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
  47.                 wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
  48.                 wmParams.format = PixelFormat.RGBA_8888;

  49.                 wm.addView(view, wmParams);

  50.                 view.setOnTouchListener(new OnTouchListener() {
  51.                         public boolean onTouch(View v, MotionEvent event) {
  52.                                 // 获取相对屏幕的坐标,即以屏幕左上角为原点
  53.                                 x = event.getRawX();
  54.                                 // 25是系统状态栏的高度,也可以通过方法得到准确的值,自己微调就是了
  55.                                 y = event.getRawY()-25 ;
  56.                                 switch (event.getAction()) {
  57.                                 case MotionEvent.ACTION_DOWN:
  58.                                         // 获取相对View的坐标,即以此View左上角为原点
  59.                                         mTouchStartX = event.getX();
  60.                                         mTouchStartY = event.getY()+view.getHeight()/2;
  61.                                         break;
  62.                                 case MotionEvent.ACTION_MOVE:
  63.                                         updateViewPosition();
  64.                                         break;
  65.                                 case MotionEvent.ACTION_UP:
  66.                                         updateViewPosition();
  67.                                         mTouchStartX = mTouchStartY = 0;
  68.                                         break;
  69.                                 }
  70.                                 return true;
  71.                         }

  72.                 });
  73.         }
  74.        
  75.         private void updateViewPosition() {
  76.                 // 更新浮动窗口位置参数
  77.                 wmParams.x = (int) (x - mTouchStartX);
  78.                 wmParams.y = (int) (y - mTouchStartY);
  79.                 wm.updateViewLayout(view, wmParams);
  80.         }

  81.         @Override
  82.         public IBinder onBind(Intent intent) {
  83.                 return null;
  84.         }
  85. }

原创粉丝点击