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,表示彈出窗口應該始終位於屏幕座標中。其目的和方式一類似。

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