本帖最后由 锋翼 于 2012-1-9 22:01 编辑
不知道有没有童鞋用过QQ的Android版本中的一个高清版本,当你退出QQ的时候,会在你的屏幕上出现一个QQ图标的悬浮窗,就和PC上的迅雷的悬浮窗口一样,在所有应用的最上层,本来这个功能感觉还是挺好的,结果TX就给流氓了下,居然没有做隐藏掉这个悬浮窗的功能。
今天就来为大家简单介绍下这个悬浮窗的实现方法吧,不过记住至少还是给用户做一个隐藏掉这个悬浮窗的功能吧!其实实现原理还是挺简单的,就是利用WindowManager将你的图标View添加到窗口中,不知道大家知道WindowManager.LayoutParams中有一个type属性不,这里玄机挺大的,找了好久,终于给我试出来有一个 TYPE_PHONE可以来实现这个功能的,该类型提供与用户交互,置于所有应用程序上方,但是在状态栏后面。至于其他的类型,大家还是去找API或者GG吧。
先看下效果图吧:
红框圈中得图标可以任意拖动哦,你可以根据自己的实际需要给图标添加功能。
核心代码如下:
不知道有没有童鞋用过QQ的Android版本中的一个高清版本,当你退出QQ的时候,会在你的屏幕上出现一个QQ图标的悬浮窗,就和PC上的迅雷的悬浮窗口一样,在所有应用的最上层,本来这个功能感觉还是挺好的,结果TX就给流氓了下,居然没有做隐藏掉这个悬浮窗的功能。
今天就来为大家简单介绍下这个悬浮窗的实现方法吧,不过记住至少还是给用户做一个隐藏掉这个悬浮窗的功能吧!其实实现原理还是挺简单的,就是利用WindowManager将你的图标View添加到窗口中,不知道大家知道WindowManager.LayoutParams中有一个type属性不,这里玄机挺大的,找了好久,终于给我试出来有一个 TYPE_PHONE可以来实现这个功能的,该类型提供与用户交互,置于所有应用程序上方,但是在状态栏后面。至于其他的类型,大家还是去找API或者GG吧。
先看下效果图吧:

红框圈中得图标可以任意拖动哦,你可以根据自己的实际需要给图标添加功能。
核心代码如下:
- 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;
- }
- }