为你的应用添加悬浮窗功能

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

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

\" data-mce-src=\" src=
红框圈中得图标可以任意拖动哦,你可以根据自己的实际需要给图标添加功能。

核心代码如下:

package com.apkstory.service;
import com.apkstory.R;

import com.apkstory.util.MyApplication;
import android.app.Service;

import android.content.Intent;

import android.graphics.PixelFormat;

import android.os.IBinder;

import android.view.Gravity;

import android.view.LayoutInflater;

import android.view.MotionEvent;

import android.view.View;

import android.view.WindowManager;

import android.view.View.OnTouchListener;
/**

* 悬浮窗的制作

*
@author 锋翼

*
@link www.apkstory.com

*/

public class TopFloatService extends Service {
WindowManager wm = null;

WindowManager.LayoutParams wmParams = null;

View view;

private float mTouchStartX;

private float mTouchStartY;

private float x;

private float y;


@Override

public void onCreate() {

super.onCreate();

view = LayoutInflater.from(this).inflate(R.layout.floating, null);

createView();

}
private void createView() {

// 获取WindowManager

wm = (WindowManager) getApplicationContext().getSystemService("window");

// 设置LayoutParams(全局变量)相关参数

wmParams = ((MyApplication) getApplication()).getMywmParams();

wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;// 该类型提供与用户交互,置于所有应用程序上方,但是在状态栏后面

wmParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;// 不接受任何按键事件

wmParams.gravity = Gravity.LEFT | Gravity.TOP; // 调整悬浮窗口至左上角

// 以屏幕左上角为原点,设置x、y初始值

wmParams.x = 0;

wmParams.y = 0;

// 设置悬浮窗口长宽数据

wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;

wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;

wmParams.format = PixelFormat.RGBA_8888;
wm.addView(view, wmParams);
view.setOnTouchListener(new OnTouchListener() {

public boolean onTouch(View v, MotionEvent event) {

// 获取相对屏幕的坐标,即以屏幕左上角为原点

x = event.getRawX();

// 25是系统状态栏的高度,也可以通过方法得到准确的值,自己微调就是了

y = event.getRawY()-25 ;
switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

// 获取相对View的坐标,即以此View左上角为原点

mTouchStartX = event.getX();

mTouchStartY = event.getY()+view.getHeight()/2;

break;

case MotionEvent.ACTION_MOVE:

updateViewPosition();

break;

case MotionEvent.ACTION_UP:

updateViewPosition();

mTouchStartX = mTouchStartY = 0;

break;

}

return true;

}
});

}


private void updateViewPosition() {

// 更新浮动窗口位置参数

wmParams.x = (int) (x - mTouchStartX);

wmParams.y = (int) (y - mTouchStartY);

wm.updateViewLayout(view, wmParams);

}
@Override

public IBinder onBind(Intent intent) {

return null;

}

}

转自:http://www.eoeandroid.com/code/2012/0209/747.html

原文地址:https://www.cnblogs.com/shanzei/p/2413895.html