1、在Application中加入
private WindowManager.LayoutParams windowParams = new WindowManager.LayoutParams();
public WindowManager.LayoutParams getWindowParams() {
return windowParams;
}
2、自定义FloatView
public class FloatView extends ImageView {
private float mTouchX;
private float mTouchY;
private float x;
private float y;
private float mStartX;
private float mStartY;
private OnClickListener mClickListener;
private WindowManager windowManager = (WindowManager) getContext()
.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
// 此windowManagerParams变量为获取的全局变量,用以保存悬浮窗口的属性
private WindowManager.LayoutParams windowManagerParams = ((FloatApplication) getContext()
.getApplicationContext()).getWindowParams();
public FloatView(Context activity) {
super(activity);
}
int statusBarHeight;
@Override
public boolean onTouchEvent(MotionEvent event) {
//获取到状态栏的高度
Rect frame = new Rect();
getWindowVisibleDisplayFrame(frame);
statusBarHeight = frame.top - 48;
// 获取相对屏幕的坐标,即以屏幕左上角为原点
x = event.getRawX();
y = event.getRawY() - statusBarHeight; // statusBarHeight是系统状态栏的高度
Log.i("aaa", "currX" + x + "====currY" + y);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: // 捕获手指触摸按下动作
// 获取相对View的坐标,即以此View左上角为原点
mTouchX = event.getX();
mTouchY = event.getY();
mStartX = x;
mStartY = y;
Log.i("aaa", "mTouchX" + mTouchX + "====mTouchY"
+ mTouchY);
break;
case MotionEvent.ACTION_MOVE: // 捕获手指触摸移动动作
updateViewPosition();
break;
case MotionEvent.ACTION_UP: // 捕获手指触摸离开动作
updateViewPosition();
if (Math.abs(x - mStartX) < 3 && Math.abs(y - mStartY) < 3) {
if(mClickListener!=null) {
mClickListener.onClick(this);
}
}
break;
}
return true;
}
@Override
public void setOnClickListener(OnClickListener l) {
this.mClickListener = l;
}
private void updateViewPosition() {
Log.i("aaa","up_x---"+x+"up_mTouchX--"+mTouchX);
Log.i("aaa","up_y---"+x+"up_mTouchY--"+mTouchY);
// 更新浮动窗口位置参数
if(Math.abs(x - mStartX) >= 3 || Math.abs(y - mStartY) >= 3){
windowManagerParams.x = (int) (x - mTouchX);
windowManagerParams.y = (int) (y - mTouchY);
windowManager.updateViewLayout(this, windowManagerParams); // 刷新显示
}
}
}
3、Activity中配置
private void createView() {
floatView = new FloatView(getApplicationContext());
floatView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getBaseContext(), "Clicked", Toast.LENGTH_SHORT).show();
}
});
floatView.setImageResource(R.mipmap.ic_launcher); // 这里简单的用自带的icon来做演示
// 获取WindowManager
windowManager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
// 设置LayoutParams(全局变量)相关参数
windowManagerParams = ((FloatApplication) getApplication()).getWindowParams();
windowManagerParams.type = WindowManager.LayoutParams.TYPE_PHONE; // 设置window type
windowManagerParams.format = PixelFormat.RGBA_8888; // 设置图片格式,效果为背景透明
// 设置Window flag
windowManagerParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
/*
* 注意,flag的值可以为:
* 下面的flags属性的效果形同“锁定”。
* 悬浮窗不可触摸,不接受任何事件,同时不影响后面的事件响应。
* LayoutParams.FLAG_NOT_TOUCH_MODAL 不影响后面的事件
* LayoutParams.FLAG_NOT_FOCUSABLE 不可聚焦
* LayoutParams.FLAG_NOT_TOUCHABLE 不可触摸
*/
// 调整悬浮窗口至左上角,便于调整坐标
windowManagerParams.gravity = Gravity.LEFT | Gravity.TOP;
// 以屏幕左上角为原点,设置x、y初始值,
Point size = new Point();//获取屏幕的size
getWindowManager().getDefaultDisplay().getSize(size);
- windowManagerParams.x = size.x-(int)(0.25*size.x);
windowManagerParams.y = size.y-(int)(0.3*size.y);
// 设置悬浮窗口长宽数据
windowManagerParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
windowManagerParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
// 显示myFloatView图像
windowManager.addView(floatView, windowManagerParams);
}
@Override
protected void onPause() {
super.onPause();
windowManager.removeView(floatView);//重点,remove调
floatView,不然会一直留在屏幕上的}
总结:
1、切记,记得在合适的地方remove掉
floatView。。我是在
onPause()方法中remove的...
2、不要忘记添加权限
<
uses-permission
android
:name=
"android.permission.SYSTEM_ALERT_WINDOW"
/>