我有这段代码。
PopupWindow popUp = new PopupWindow();
popUp.setFocusable(true);
popUp.setOutsideTouchable(true);
popUp.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
popUp.setHeight(600);
popUp.setContentView(anchorView);
popUp.showAsDropDown(anchorView);
popUp.update();
它完美适用于Android版本< Android Nougat。但在Android Nougat中,弹出窗口显示在屏幕顶部而不是相对于锚点视图。
答案 0 :(得分:16)
这似乎是android 7.0中的一个错误。但你可以用一个解决它 兼容的方式。
PopupWindow popUp = new PopupWindow();
popUp.setFocusable(true);
popUp.setOutsideTouchable(true);
popUp.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
popUp.setHeight(600);
popUp.setContentView(anchorView);
if (android.os.Build.VERSION.SDK_INT >=24) {
int[] a = new int[2]; //getLocationInWindow required array of size 2
anchorView.getLocationInWindow(a);
popUp.showAtLocation(((Activity) mContext).getWindow().getDecorView(), Gravity.NO_GRAVITY, 0 , a[1]+anchorView.getHeight());
} else{
popUp.showAsDropDown(anchorView);
}
popUp.update();
Google将在未来版本中修复此错误。还有最后的解决方法。你需要在创建pop时给出高度。
PopupWindow popup = new PopupWindow(contentView, with, height);
如上弹出弹出,你只能使用 popUp.showAsDropDown(anchorView)显示此弹出窗口。这样,您就可以忽略Android API的版本。
答案 1 :(得分:5)
7.0和7.1实现不同,所以要单独处理。
我在虚拟机(7.0和7.1)中测试过以下方法,没问题。
public void showFilterWindow(Context context, PopupWindow popupWindow,View showView, int xoff, int yoff) {
if (Build.VERSION.SDK_INT < 24) {
//7.0 The following system is used normally
popupWindow.showAsDropDown(showView, xoff, yoff);
} else {
int[] location = new int[2];
showView.getLocationOnScreen(location);
int offsetY = location[1] + showView.getHeight() + yoff;
if (Build.VERSION.SDK_INT == 25) {
//【note!】Gets the screen height without the virtual key
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
int screenHeight = wm.getDefaultDisplay().getHeight();
/*
* PopupWindow height for match_parent,
* will occupy the entire screen, it needs to do special treatment in Android 7.1
*/
popupWindow.setHeight(screenHeight - offsetY);
}
//Use showAtLocation to display pop-up windows
popupWindow.showAtLocation(showView, Gravity.NO_GRAVITY, 0, offsetY);
}
}
答案 2 :(得分:2)
看起来此问题仅出现在Android 7.0(API 24)中。在7.1.1(API 25)中,在同一设备上一切正常。经过一些研究确定问题由popUp.update()
引起,就像Marilia已经提到的那样。但是如果您只是删除popUp.update()
,弹出窗口将不会出现在API 24之前的版本中。为了避免这种情况,现在唯一的方法是使用版本检查而不要仅使用update()
方法在具有API 24的设备上。这是解决方案,对我有用:
if (Build.VERSION.SDK_INT != 24) {
popup.update(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
}
在不同的设备和API上进行测试,无论从API 18到API 25,它都能正常运行。
答案 3 :(得分:1)
您的代码中确实需要popUp.update();
吗?我遇到了类似的问题,在我的情况下,我并不需要popUp.update();
并删除它使弹出重力按预期运行。
此外,这很可能是一个相关问题,报告了PopupWindow.showAtLocation()
:
答案 4 :(得分:0)
此代码对我有用。请尝试
protected void showSortPopup(View anchorView) {
if (Build.VERSION.SDK_INT >= 25) {
Rect rectf = new Rect();
anchorView.getGlobalVisibleRect(rectf);
int offsetY = (rectf.top + anchorView.getHeight());
WindowManager wm = (WindowManager) Manager.getInstance().getCurrentActivity().getSystemService(Context.WINDOW_SERVICE);
int screenHeight = wm.getDefaultDisplay().getHeight();
mPopup.setHeight(screenHeight - offsetY);
}
mPopup.showAsDropDown(anchorView);
}
答案 5 :(得分:0)
在Android API 29中,我通过将弹出窗口的宽度和高度替换为WRAP_CONTENT
进行了修复。就像我在 Kotlin 中的代码一样。
private fun createSpinnerLikePopUp() {
val inflater = context?.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val vw = inflater.inflate(R.layout.dialog_window, null, false)
popUp = PopupWindow(context).apply {
isFocusable = true
width = WindowManager.LayoutParams.WRAP_CONTENT
height = WindowManager.LayoutParams.WRAP_CONTENT
contentView = vw
setBackgroundDrawable(null)
}
vw!!.recyclerView.apply {
layoutManager = LinearLayoutManager(context)
adapter = RecyclerAdapter(context, myArray)
}
}
然后单击按钮,如下所示:
displayPopupBtn.setOnClickListener { view ->
if (popUp != null) {
if (popUp.isShowing) {
popUp.dismiss()
} else {
popUp.showAsDropDown(view)
}
}
}