声明权限:<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
获得 WindowManager
mWindowManager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
生成LayoutParams
mLayoutParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, 2099,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
PixelFormat.TRANSPARENT);
WindowManager.LayoutParams 构参
构造参数:LayoutParams(int w, int h, int _type, int _flags, int _format)
_type:
- 应用window的层级范围:1-99
- 子window的层级范围:1000-1999
- 系统window的层级范围:2000-2999
_flags:
- FLAG_NOT_TOUCH_MODAL:自己区域内事件自己处理,区域外事件传递给底层window处理。一般默认开启。否则其他window无法获得事件
- FLAG_NOT_FOCUSABLE:window不需要获取焦点,把焦点传递给下层window。
- FLAG_SHOW_WHEN_LOCKED:可以显示在锁屏界面上。
示例代码
public class MainActivity extends AppCompatActivity implements View.OnTouchListener {
private WindowManager mWindowManager;
private ImageView mImageView;
private WindowManager.LayoutParams mLayoutParams;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWindowManager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
mImageView = new ImageView(this);
mImageView.setBackgroundResource(R.mipmap.ic_launcher);
mLayoutParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, 2099,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
PixelFormat.TRANSPARENT);
mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
mLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
mLayoutParams.x = 0;
mLayoutParams.y = 300;
mImageView.setOnTouchListener(this);
mWindowManager.addView(mImageView, mLayoutParams);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
int rawX = (int) event.getRawX();
int rawY = (int) event.getRawY();
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE: {
mLayoutParams.x = rawX;
mLayoutParams.y = rawY;
mWindowManager.updateViewLayout(mImageView, mLayoutParams);
break;
}
default:
break;
}
return false;
}
@Override
protected void onDestroy() {
try {
mWindowManager.removeView(mImageView);
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
super.onDestroy();
}
}