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;