概要
窗口(Window)的概念平时并不是很常用,但有时候我们需要创建一个悬浮窗,这时候就需要使用Window来实现,通过WindowManager来添加一个Window,Window是一个抽象的概念,以View的形式存在。
WindowManager类
WindowManager正如其名,是外界访问Window的入口。WindowManager提供了三个方法。
addView()方法
public void addView(View view, ViewGroup.LayoutParams params)
添加view到窗口
- view:需要添加到窗口的view
- params:用于配置创建的窗口信息
//在安卓6.0及以后需要判断是否具有权限(是否允许应用出现在其他应用之上)
if (Build.VERSION.SDK_INT >= 23) {
//如果已勾选“出现在其他应用之上”
if (Settings.canDrawOverlays(MainActivity.this)) {
showFloatView();
} else {
//否则进入打开权限界面有用户手动授权
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
startActivity(intent);
}
} else {
showFloatView();
}
void showFloatView(){
//这里以创建一个悬浮的ImageView为例
ImageView floatView = new ImageView(this);
floatView.setImageResource(R.drawable.img_1);
//创建一个WindowManager对象
WindowManager windowManager = (WindowManager) getApplication().getSystemService(getApplication().WINDOW_SERVICE);
//使用LayoutParams配置窗口信息,这里直接在构造方法中设置,也可以创建后设置
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT, //设置窗口大小,此处为包裹内容
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE, //悬浮在所有窗口之上
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, //不获取焦点
PixelFormat.TRANSLUCENT); //透明?
params.gravity = Gravity.TOP | Gravity.LEFT; //设置窗口对齐方式
params.x = 0;
params.y = 100;
windowManager.addView(floatView, params); //显示窗口,对应为removeView()
}
removeView()方法
public void removeView(View view)
从窗口移除view
updateViewLayout()方法
public void updateViewLayout(View view, ViewGroup.LayoutParams params)
更新view的显示。
通常需要监听view的触摸事件,获取坐标等数据,然后在params变量中重新填充数据,调用此方法更新即可。
ViewGroup.LayoutParams类
- 常用flag
- FLAG_NOT_FOCUSALBE:不获取焦点,同时会启用FLAG_NOT_TOUCH_MODAL。
- FLAG_NOT_TOUCH_MODAL:开启后系统会将window区域之外的点击事件传递给底层的window,区域之内由自己处理,一般需要开启,否则无法响应单击事件。
- FLAG_SHOW_WHEN_LOCKED:让window显示在锁屏界面上。
- x、y:窗口显示的位置
- width、height:窗口的宽高
- gravity:窗口显示的对齐方式
- type:窗口类型
- format:The desired bitmap format. May be one of the constants in PixelFormat. Default is OPAQUE.(不是很理解,暂时把原话搬过来)