主要記錄PopupWindow自己計算彈出位置的方法
小編推薦
自己開發app到上架應用市場需要經曆什麼?https://www.cnblogs.com/popfisher/p/14218431.html
說到PopupWindow,應該都會有種熟悉的感覺,使用起來也很簡單
// 一個自定義的布局,作為顯示的内容
Context context = null; // 真實環境中要指派
int layoutId = 0; // 布局ID
View contentView = LayoutInflater.from(context).inflate(layoutId, null);
final PopupWindow popupWindow = new PopupWindow(contentView,
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, true);
popupWindow.setTouchable(true);
// 如果不設定PopupWindow的背景,有些版本就會出現一個問題:無論是點選外部區域還是Back鍵都無法dismiss彈框
// 這裡單獨寫一篇文章來分析
popupWindow.setBackgroundDrawable(new ColorDrawable());
// 設定好參數之後再show
popupWindow.showAsDropDown(contentView);
如果建立PopupWindow的時候沒有指定高寬,那麼showAsDropDown預設隻會向下彈出顯示,這種情況有個最明顯的缺點就是:彈視窗可能被螢幕截斷,顯示不全,是以需要使用到另外一個方法showAtLocation,這個的坐标是相對于整個螢幕的,是以需要我們自己計算位置。
如下圖所示,我們可以根據螢幕左上角的坐标A,螢幕高寬,點選View的左上角的坐标C,點選View的大小以及PopupWindow布局的大小計算出PopupWindow的顯示位置B
計算方法源碼如下:
/**
* 計算出來的位置,y方向就在anchorView的上面和下面對齊顯示,x方向就是與螢幕右邊對齊顯示
* 如果anchorView的位置有變化,就可以适當自己額外加入偏移來修正
* @param anchorView 呼出window的view
* @param contentView window的内容布局
* @return window顯示的左上角的xOff,yOff坐标
*/
private static int[] calculatePopWindowPos(final View anchorView, final View contentView) {
final int windowPos[] = new int[2];
final int anchorLoc[] = new int[2];
// 擷取錨點View在螢幕上的左上角坐标位置
anchorView.getLocationOnScreen(anchorLoc);
final int anchorHeight = anchorView.getHeight();
// 擷取螢幕的高寬
final int screenHeight = ScreenUtils.getScreenHeight(anchorView.getContext());
final int screenWidth = ScreenUtils.getScreenWidth(anchorView.getContext());
contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
// 計算contentView的高寬
final int windowHeight = contentView.getMeasuredHeight();
final int windowWidth = contentView.getMeasuredWidth();
// 判斷需要向上彈出還是向下彈出顯示
final boolean isNeedShowUp = (screenHeight - anchorLoc[1] - anchorHeight < windowHeight);
if (isNeedShowUp) {
windowPos[0] = screenWidth - windowWidth;
windowPos[1] = anchorLoc[1] - windowHeight;
} else {
windowPos[0] = screenWidth - windowWidth;
windowPos[1] = anchorLoc[1] + anchorHeight;
}
return windowPos;
}
接下來調用showAtLoaction顯示:
View windowContentViewRoot = 我們要設定給PopupWindow進行顯示的View
int windowPos[] = calculatePopWindowPos(view, windowContentViewRoot);
int xOff = 20;// 可以自己調整偏移
windowPos[0] -= xOff;
popupwindow.showAtLocation(view, Gravity.TOP | Gravity.START, windowPos[0], windowPos[1]);
// windowContentViewRoot是根布局View
上面的例子隻是提供了一種計算方式,在實際開發中可以根據需求自己計算,比如anchorView在左邊的情況,在中間的情況,可以根據實際需求寫一個彈出位置能夠自适應的PopupWindow。
補充上擷取螢幕高寬的代碼ScreenUtils.java:
/**
* 擷取螢幕高度(px)
*/
public static int getScreenHeight(Context context) {
return context.getResources().getDisplayMetrics().heightPixels;
}
/**
* 擷取螢幕寬度(px)
*/
public static int getScreenWidth(Context context) {
return context.getResources().getDisplayMetrics().widthPixels;
}
Demo截圖展示:
看完覺得有用記得點選推薦支援一下,謝謝
Demo下載下傳位址:https://github.com/PopFisher/SmartPopupWindow