Android悬浮窗自由移动实现

jopen 11年前

      网上很多这方面的文章,但总有诸多问题。主要有:一、悬浮窗移动手指离开后,再次移动时,悬浮窗自动回到初始位置开始移动。二、悬浮窗总是不肯老实地呆在手指边,手指点上去时会有一些不正常的位移。三、把状态栏的高度默认为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;