PopupWindow全屏显示适配所有机型

近期有一个类似咸鱼发布功能的需求,这里使用了PopupWindow去实现所有的效果,但是在UI走查阶段,OPPO的一款手机无法全屏,状态栏没有遮盖,此处记录解决过程。

部分初始重要代码:

public class MyPopWindow extends PopupWindow implements View.OnClickListener {
    private View rootView;
    private RelativeLayout contentView;
    private Activity mContext;

    public MyPopWindow(Activity context) {
        this.mContext = context;
    }

    @RequiresApi(api = Build.VERSION_CODES.CUPCAKE)
    public void showMoreWindow(View anchor) {
        LayoutInflater inflater = (LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        rootView = inflater.inflate(R.layout.dialog_centre, null);
        initView();
        showAtLocation(anchor, Gravity.BOTTOM, 0, 0);
    }

    private void initView() {
        setContentView(rootView);
        setWidth(mContext.getWindowManager().getDefaultDisplay().getWidth());
        setHeight(mContext.getWindowManager().getDefaultDisplay().getHeight());
        setBackgroundDrawable(new BitmapDrawable());
        setFocusable(true);

    }
}

方式一:

添加以下属性会解决大部分机型问题包括Build.VERSION.SDK_INT大于21的:

setClippingEnabled(false);

但是此时OPPO机型 Build.VERSION.SDK_INT=27却还是存在状态栏未遮盖问题。

方式二:

添加以下方法完美解决了遗留的问题,nice!

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            try {
                Field mLayoutInScreen = PopupWindow.class.getDeclaredField("mLayoutInScreen");
                mLayoutInScreen.setAccessible(true);
                mLayoutInScreen.set(this, true);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

总结:

第一种解决方式官方注释是允许弹出窗口超出屏幕边界。默认情况下,窗口被剪切到屏幕边界。将此设置为false将允许窗口为准确定位。这个时候我去设置它的宽高为屏幕宽高通常是可行的。

第二种解决方式是判断当Build.VERSION.SDK_INT大于21时对其做特殊处理,也就是通过反射获得mLayoutInScreen属性,并且设置其值为true,官方解释允许弹窗强制去标记,覆盖默认行为。这将导致弹出窗口被定位在绝对屏幕座标。启用true,表示弹出窗口应该始终位于屏幕座标中。其目的和方式一类似。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章