PopupWindow 高度是match_parent的時候,鋪滿全屏的問題

問題

在以前,我們一直使用showAsDropDown 來讓PopupWindow 顯示在某個anchor的下邊,哪怕這個PopupWindow高度是match_parent的,可24以后,你會發(fā)現(xiàn),它不再是顯示在anchor下邊,而是鋪滿整個屏幕的,把anchor都蓋住了.

簡單的使用

        val popup=PopupWindow(WindowManager.LayoutParams.MATCH_PARENT,WindowManager.LayoutParams.MATCH_PARENT).apply {
            contentView=LayoutInflater.from(baseContext).inflate(R.layout.popup_test,null)
            this.isTouchable=true
            this.isFocusable=true;

        }

popup.showAsDropDown(tg)

我們分析下7.0和6.0的源碼有啥區(qū)別

6.0的源碼

    public void showAtLocation(IBinder token, int gravity, int x, int y) {
        if (isShowing() || mContentView == null) {
            return;
        }

        TransitionManager.endTransitions(mDecorView);

        unregisterForScrollChanged();

        mIsShowing = true;
        mIsDropdown = false;

        final LayoutParams p = createPopupLayoutParams(token);
        preparePopup(p);

        // Only override the default if some gravity was specified.
        if (gravity != Gravity.NO_GRAVITY) {
            p.gravity = gravity;
        }

        p.x = x;
        p.y = y;

        invokePopup(p);
    }

7.0的源碼

    public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) {
        if (isShowing() || !hasContentView()) {
            return;
        }

        TransitionManager.endTransitions(mDecorView);

        attachToAnchor(anchor, xoff, yoff, gravity);

        mIsShowing = true;
        mIsDropdown = true;

        final WindowManager.LayoutParams p =
                createPopupLayoutParams(anchor.getApplicationWindowToken());
        preparePopup(p);

        final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff,
                p.width, p.height, gravity, mAllowScrollingAnchorParent);
        updateAboveAnchor(aboveAnchor);
        p.accessibilityIdOfAnchor = (anchor != null) ? anchor.getAccessibilityViewId() : -1;

        invokePopup(p);
    }

可以看到7.0的多了兩行代碼,看名字aboveAnchor,它會判斷是否顯示在anchor上

        final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff,
                p.width, p.height, gravity, mAllowScrollingAnchorParent);
        updateAboveAnchor(aboveAnchor);

在分析這兩行代碼之前,先看下默認生成個的params里的高度是啥
進入createPopupLayoutParams方法
mHeightMode :默認是0,如果你沒設(shè)置的話,我們一般都沒設(shè)置這個,所以會走else
而mHeight,我們在構(gòu)造方法里設(shè)置的是match_parent也就是-1

protected final WindowManager.LayoutParams createPopupLayoutParams(IBinder token) {

        if (mHeightMode < 0) {
            p.height = mLastHeight = mHeightMode;
        } else {
            p.height = mLastHeight = mHeight;
        }
}

然后繼續(xù)看findDropDownPosition

 protected boolean findDropDownPosition(View anchor, WindowManager.LayoutParams outParams,
            int xOffset, int yOffset, int width, int height, int gravity, boolean allowScroll) {
//...
final Rect displayFrame = new Rect();
        appRootView.getWindowVisibleDisplayFrame(displayFrame);
//...可以看到,高度就是整個容器的高度,差不多就是屏幕的高度了
        if (height == MATCH_PARENT) {
            height = displayFrame.bottom - displayFrame.top;
        }

//...下邊會判斷我們這個高度是否會超出屏幕,如果超出屏幕的話,會返回false
        // First, attempt to fit the popup vertically without resizing.
        final boolean fitsVertical = tryFitVertical(outParams, yOffset, height,
                anchorHeight, drawingLocation[1], screenLocation[1], displayFrame.top,
                displayFrame.bottom, false);
}
//...下邊會處理false的情況的,會都params的y進行處理的,處理結(jié)果就是,y的位置不再是anchor下邊了,因為 Popup高度是屏幕高度了,所以y差不多就是0了.具體就不分析了
 // If the popup still doesn't fit, attempt to scroll the parent.
        if (!fitsVertical || !fitsHorizontal) {

}

總結(jié)

看完源碼就發(fā)現(xiàn)了,24以上,match_parent的話,Popup的高度就是全屏高度了,所以,如果還想顯示在anchor下邊,那就只能用wrap_content,或者 自己計算下anchor底部到屏幕底部的距離,也就是Popup需要展示的高度,自己手動setHeight

計算anchor或者容器的位置大小也很簡單,下邊這種就行

final Rect displayFrame = new Rect();
        appRootView.getWindowVisibleDisplayFrame(displayFrame);
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容