1. 程式人生 > >為你的應用新增懸浮框

為你的應用新增懸浮框

不知道有沒有童鞋用過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.         @Override
  28.         public void onCreate() {
  29.                 super.onCreate();
  30.                 view = LayoutInflater.from(this).inflate(R.layout.floating, null);
  31.                 createView();
  32.         }
  33.         private void createView() {
  34.                 // 獲取WindowManager
  35.                 wm = (WindowManager) getApplicationContext().getSystemService("window");
  36.                 // 設定LayoutParams(全域性變數)相關引數
  37.                 wmParams =  ((MyApplication) getApplication()).getMywmParams();
  38.                 wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;// 該型別提供與使用者互動,置於所有應用程式上方,但是在狀態列後面
  39.                 wmParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;// 不接受任何按鍵事件
  40.                 wmParams.gravity = Gravity.LEFT | Gravity.TOP; // 調整懸浮視窗至左上角
  41.                 // 以螢幕左上角為原點,設定x、y初始值
  42.                 wmParams.x = 0;
  43.                 wmParams.y = 0;
  44.                 // 設定懸浮視窗長寬資料
  45.                 wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
  46.                 wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
  47.                 wmParams.format = PixelFormat.RGBA_8888;
  48.                 wm.addView(view, wmParams);
  49.                 view.setOnTouchListener(new OnTouchListener() {
  50.                         public boolean onTouch(View v, MotionEvent event) {
  51.                                 // 獲取相對螢幕的座標,即以螢幕左上角為原點
  52.                                 x = event.getRawX();
  53.                                 // 25是系統狀態列的高度,也可以通過方法得到準確的值,自己微調就是了
  54.                                 y = event.getRawY()-25 ; 
  55.                                 switch (event.getAction()) {
  56.                                 case MotionEvent.ACTION_DOWN:
  57.                                         // 獲取相對View的座標,即以此View左上角為原點
  58.                                         mTouchStartX = event.getX();
  59.                                         mTouchStartY = event.getY()+view.getHeight()/2;
  60.                                         break;
  61.                                 case MotionEvent.ACTION_MOVE:
  62.                                         updateViewPosition();
  63.                                         break;
  64.                                 case MotionEvent.ACTION_UP:
  65.                                         updateViewPosition();
  66.                                         mTouchStartX = mTouchStartY = 0;
  67.                                         break;
  68.                                 }
  69.                                 return true;
  70.                         }
  71.                 });
  72.         }
  73.         private void updateViewPosition() {
  74.                 // 更新浮動視窗位置引數
  75.                 wmParams.x = (int) (x - mTouchStartX);
  76.                 wmParams.y = (int) (y - mTouchStartY);
  77.                 wm.updateViewLayout(view, wmParams);
  78.         }
  79.         @Override
  80.         public IBinder onBind(Intent intent) {
  81.                 return null;
  82.         }
  83. }
複製程式碼