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