悬浮窗的层级

最近需要实现在白板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达到了目的,悬浮窗显示在所有白板窗口的下方。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。