Android懸浮窗自由移動實現

jopen 11年前發布 | 43K 次閱讀 Android Android開發 移動開發

      網上很多這方面的文章,但總有諸多問題。主要有:一、懸浮窗移動手指離開后,再次移動時,懸浮窗自動回到初始位置開始移動。二、懸浮窗總是不肯老實地呆在手指邊,手指點上去時會有一些不正常的位移。三、把狀態欄的高度默認為25。【不同分辨率的狀態欄會一樣高嗎?】更有甚者,好多直接在兩次相減中把這個值給消掉了。事實上,這個值根本就是不需要設置的。

     項目中要用到這個功能,自己研究了一下,貼出關鍵功能代碼。其他代碼請自行問谷歌。

    懸浮窗初始化及監聽Touch事件。

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;
                }
            });


更新位置:

 private void updateViewPosition() {
        // 更新浮動窗口位置參數
        wmParams.x = (int) (x - mTouchStartX);
        wmParams.y = (int) (y - mTouchStartY);
        wm.updateViewLayout(view, wmParams);

    }

一些變量:

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;

 

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!