這里主要記錄一次踩坑的經(jīng)歷残腌。
需求:如上圖左側(cè)效果叠艳,想在按鈕的下方彈一個PopupWindow烁登。嗯职烧,很簡單一個效果,然當適配7.0后發(fā)現(xiàn)這個PopupWindow顯示異常防泵,然后網(wǎng)上找到了下面這種方案蚀之。
image.png
7.0適配方案(但7.1又復現(xiàn)了)
// 將popupWindow顯示在anchor下方
public void showAsDropDown(PopupWindow popupWindow, View anchor) {
if (Build.VERSION.SDK_INT < 24) {
popupWindow.showAsDropDown(anchor);
} else {
// 適配 android 7.0
int[] location = new int[2];
// 獲取控件在屏幕的位置
anchor.getLocationOnScreen(location);
popupWindow.showAtLocation(anchor, Gravity.NO_GRAVITY, 0, location[1] + anchor.getHeight());
}
}
然后我那個開心啊,然后我就告訴其他人popwindow 在7.0 (SDK=24)適配的問題,然后所有popwindow都這么更改了捷泞。
尷尬的是7.1 (SDK=25)上又復現(xiàn)了這個問題足删,顯示異常。
最終解決方案
if (Build.VERSION.SDK_INT < 24) {
mPopupWindow = new FixedPopupWindow(popView, ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
} else {
int[] location = new int[2];
// 獲取控件在屏幕的位置
anchor.getLocationOnScreen(location);
int screenHeight = getScreenHeightPixels(context);
mPopupWindow = new PopupWindow(popView, ViewGroup.LayoutParams.MATCH_PARENT,
screenHeight - (location[1] + anchor.getHeight()));
}
在初始化的時候通過動態(tài)設置高度來完成顯示效果锁右。此時我們直接調(diào)用顯示就行了失受。
mPopupWindow.showAsDropDown(anchor);
小思考
當項目中公用PopupWindow的時候,你一定想著封裝一次咏瑟,畢竟PopupWindow的初始化也是一個體力活拂到。于是,可以將這種適配方案直接在showAsDropDown()
方法中實現(xiàn)码泞。
import android.graphics.Rect;
import android.os.Build;
import android.view.View;
import android.widget.PopupWindow;
/**
* Created by smart on 2018/5/15.
*/
public class FixedPopupWindow extends PopupWindow {
public FixedPopupWindow(View contentView, int width, int height){
super(contentView, width, height);
}
.....
@Override
public void showAsDropDown(View anchor) {
if (Build.VERSION.SDK_INT >= 24) {
Rect rect = new Rect();
anchor.getGlobalVisibleRect(rect);// 以屏幕 左上角 為參考系的
int h = anchor.getResources().getDisplayMetrics().heightPixels - rect.bottom; //屏幕高度減去 anchor 的 bottom
setHeight(h);// 重新設置PopupWindow高度
}
super.showAsDropDown(anchor);
}
...
}
與上面那種方案比較
- 兩種不同的計算高度的方法
- 都是通過設置PopupWindow的高度實現(xiàn)
- 這種封裝可以簡化重用代碼