最近需要实现在白板App中点“打开”然后选择文件再用悬浮窗展示的功能。打开文件是另外一个App,刚开始我把代码加在打开文件的这个App中,由于打开悬浮窗之后需要关闭打开文件的这个App,所以我选择先启动Serivce,然后传入Service的Context给悬浮窗进行打开,显示白板的代码如下:
package com.test.floatwindowtest;
import android.content.Context;
import android.graphics.PixelFormat;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.WindowManager;
import android.widget.RelativeLayout;
public class CustomFloatWindow extends RelativeLayout {
protected WindowManager mWindowManager;
private int mNormalWidth, mNormalHeight, mNormalOffsetX, mNormalOffsetY;
private WindowManager.LayoutParams mLayoutParams;
public CustomFloatWindow(Context context){
super(context);
mNormalWidth = DisplayUtil.dp2px(533);
mNormalHeight = DisplayUtil.dp2px(602);
mNormalOffsetX = DisplayUtil.dp2px(53);
mNormalOffsetY = DisplayUtil.dp2px(42);
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
mLayoutParams = new WindowManager.LayoutParams();
mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY ;
mLayoutParams.format = PixelFormat.RGBA_8888;
mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
LayoutInflater.from(context).inflate(R.layout.layout_float_window, this);
setGravityOffset(Gravity.LEFT | Gravity.TOP, mNormalOffsetX, mNormalOffsetY);
setSize(mNormalWidth, mNormalHeight);
}
private void setSize(int width, int height) {
mLayoutParams.width = width;
mLayoutParams.height = height;
}
private void setGravityOffset(int gravity, int xOffset, int yOffset) {
mLayoutParams.gravity = gravity;
mLayoutParams.x = xOffset;
mLayoutParams.y = yOffset;
}
public void show(){
mWindowManager.addView(this, mLayoutParams);
}
}
功能确实实现了,但是有一个问题,因为这里type使用TYPE_APPLICATION_OVERLAY,导致悬浮窗显示在所有窗口的上方,挡住了白板里的窗口。想要解决这个问题,必须调整type属性,但是低层级的悬浮窗需要传入Activity的Context,这样必须把显示悬浮窗的代码移入白板App中。这样方案改成使用startActivityForResult启动打开文件的App,拿到文件路径之后setResult返回到白板App中打开悬浮窗。当时想当然地觉得type的值越小,层级越低,于是把type改成FIRST_APPLICATION_WINDOW,但是测试之后发现层级还不是最低的。最后把type改成FIRST_SUB_WINDOW达到了目的,悬浮窗显示在所有白板窗口的下方。