網上很多這方面的文章,但總有諸多問題。主要有:一、懸浮窗移動手指離開後,再次移動時,懸浮窗自動回到初始位置開始移動。二、懸浮窗總是不肯老實地呆在手指邊,手指點上去時會有一些不正常的位移。三、把狀態欄的高度默認為25。【不同分辨率的狀態欄會一樣高嗎?】更有甚者,好多直接在兩次相減中把這個值給消掉了。事實上,這個值根本就是不需要設置的。
項目中要用到這個功能,自己研究了一下,貼出關鍵功能代碼。其他代碼請自行問谷歌。
懸浮窗初始化及監聽Touch事件。
[java
wm = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
wmParams = new WindowManager.LayoutParams();
// 設置LayoutParams(全局變量)相關參數
wmParams.type = LayoutParams.TYPE_PHONE;
wmParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL| LayoutParams.FLAG_NOT_FOCUSABLE;
wmParams.gravity = Gravity.CENTER; // 調整懸浮窗口至中間
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);
initViewPlace = false;
view.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (!initViewPlace) {
initViewPlace = true;
//獲取初始位置
mTouchStartX = event.getRawX();
mTouchStartY = event.getRawY();
x = event.getRawX();
y = event.getRawY();
Log.i(TAG, "startX:" + mTouchStartX + "=>startY:" + mTouchStartY);
}else {
//根據上次手指離開的位置與此次點擊的位置進行初始位置微調
mTouchStartX += (event.getRawX() -x);
mTouchStartY += (event.getRawY() - y);
}
break;
case MotionEvent.ACTION_MOVE:
// 獲取相對屏幕的坐標,以屏幕左上角為原點
x = event.getRawX();
y = event.getRawY();
updateViewPosition();
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
});
更新位置:
[java]
private void updateViewPosition() {
// 更新浮動窗口位置參數
wmParams.x = (int) (x - mTouchStartX);
wmParams.y = (int) (y - mTouchStartY);
wm.updateViewLayout(view, wmParams);
}
一些變量:
[java]
private static int statusBarHeight = 0;
WindowManager wm = null;
WindowManager.LayoutParams wmParams = null;
View view;
private float mTouchStartX;
private float mTouchStartY;
private float x;
private float y;
private static final String TAG = "FloatService";
boolean initViewPlace = false;