Open songchuanyang opened 1 year ago
在自己自定义的popup中现在要重写以下代码才能解决这个问题,太过繁琐
/**
* 执行倚靠逻辑
*/
float translationX = 0, translationY = 0;
// 弹窗显示的位置不能超越Window高度
float maxY = XPopupUtils.getAppHeight(getContext());
int overflow = XPopupUtils.dp2px(getContext(), 10);
float centerY = 0;
public void doAttach() {
if (popupInfo == null) return;
int realNavHeight = (XPopupUtils.isNavBarVisible(getHostWindow()) ? XPopupUtils.getNavBarHeight() : 0);
maxY = XPopupUtils.getAppHeight(getContext()) - overflow - realNavHeight;
final boolean isRTL = XPopupUtils.isLayoutRtl(getContext());
//0. 判断是依附于某个点还是某个View
if (popupInfo.touchPoint != null) {
if (XPopup.longClickPoint != null) popupInfo.touchPoint = XPopup.longClickPoint;
popupInfo.touchPoint.x -= getActivityContentLeft();
centerY = popupInfo.touchPoint.y;
// 依附于指定点,尽量优先放在下方,当不够的时候在显示在上方
//假设下方放不下,超出window高度
boolean isTallerThanWindowHeight = (popupInfo.touchPoint.y + getPopupContentView().getMeasuredHeight()) > maxY;
if (isTallerThanWindowHeight) {
isShowUp = popupInfo.touchPoint.y > XPopupUtils.getScreenHeight(getContext()) / 2f;
} else {
isShowUp = false;
}
isShowLeft = popupInfo.touchPoint.x < XPopupUtils.getAppWidth(getContext()) / 2f;
//限制最大宽高
ViewGroup.LayoutParams params = getPopupContentView().getLayoutParams();
int maxHeight = (int) (isShowUpToTarget() ? (popupInfo.touchPoint.y - XPopupUtils.getStatusBarHeight() - overflow)
: (XPopupUtils.getScreenHeight(getContext()) - popupInfo.touchPoint.y - overflow - realNavHeight));
int maxWidth = (int) (isShowLeft ? (XPopupUtils.getAppWidth(getContext()) - popupInfo.touchPoint.x - overflow) : (popupInfo.touchPoint.x - overflow));
if (getPopupContentView().getMeasuredHeight() > maxHeight) {
params.height = maxHeight;
}
if (getPopupContentView().getMeasuredWidth() > maxWidth) {
params.width = Math.max(maxWidth, getPopupWidth());
}
getPopupContentView().setLayoutParams(params);
getPopupContentView().post(new Runnable() {
@Override
public void run() {
if (popupInfo == null) return;
if (isRTL) {
translationX = isShowLeft ? -(XPopupUtils.getAppWidth(getContext()) - popupInfo.touchPoint.x - getPopupContentView().getMeasuredWidth() - defaultOffsetX)
: -(XPopupUtils.getAppWidth(getContext()) - popupInfo.touchPoint.x + defaultOffsetX);
} else {
translationX = isShowLeft ? (popupInfo.touchPoint.x + defaultOffsetX) : (popupInfo.touchPoint.x - getPopupContentView().getMeasuredWidth() - defaultOffsetX);
}
if (popupInfo.isCenterHorizontal) {
//水平居中
if (isShowLeft) {
if (isRTL) {
translationX += getPopupContentView().getMeasuredWidth() / 2f;
} else {
translationX -= getPopupContentView().getMeasuredWidth() / 2f;
}
} else {
if (isRTL) {
translationX -= getPopupContentView().getMeasuredWidth() / 2f;
} else {
translationX += getPopupContentView().getMeasuredWidth() / 2f;
}
}
}
if (isShowUpToTarget()) {
// 应显示在point上方
// translationX: 在左边就和atView左边对齐,在右边就和其右边对齐
translationY = popupInfo.touchPoint.y - getPopupContentView().getMeasuredHeight() - defaultOffsetY;
} else {
translationY = popupInfo.touchPoint.y + defaultOffsetY;
}
getPopupContentView().setTranslationX(translationX);
getPopupContentView().setTranslationY(translationY);
initAndStartAnimation();
}
});
} else {
// 依附于指定View
//1. 获取atView在屏幕上的位置
Rect rect = getAtViewRect();
rect.left -= getActivityContentLeft();
rect.right -= getActivityContentLeft();
final int centerX = (rect.left + rect.right) / 2;
// 尽量优先放在下方,当不够的时候在显示在上方
//假设下方放不下,超出window高度
boolean isTallerThanWindowHeight = (rect.bottom + getPopupContentView().getMeasuredHeight()) > maxY;
centerY = (rect.top + rect.bottom) / 2;
if (isTallerThanWindowHeight) {
//超出下方可用大小,但未超出上方可用区域就显示在上方
int upAvailableSpace = rect.top - XPopupUtils.getStatusBarHeight() - overflow;
if (getPopupContentView().getMeasuredHeight() > upAvailableSpace) {
//如果也超出了上方可用区域则哪里空间大显示在哪个方向
isShowUp = upAvailableSpace > (maxY - rect.bottom);
} else {
isShowUp = true;
}
// isShowUp = centerY > XPopupUtils.getScreenHeight(getContext()) / 2;
} else {
isShowUp = false;
}
isShowLeft = centerX < XPopupUtils.getAppWidth(getContext()) / 2;
//修正高度,弹窗的高有可能超出window区域
// if (!isCreated) {
ViewGroup.LayoutParams params = getPopupContentView().getLayoutParams();
int maxHeight = isShowUpToTarget() ? (rect.top - XPopupUtils.getStatusBarHeight() - overflow)
: (XPopupUtils.getScreenHeight(getContext()) - rect.bottom - overflow - realNavHeight);
int maxWidth = isShowLeft ? (XPopupUtils.getAppWidth(getContext()) - rect.left - overflow) : (rect.right - overflow);
if (getPopupContentView().getMeasuredHeight() > maxHeight) {
params.height = maxHeight;
}
if (getPopupContentView().getMeasuredWidth() > maxWidth) {
params.width = Math.max(maxWidth, getPopupWidth());
}
getPopupContentView().setLayoutParams(params);
// }
getPopupContentView().post(new Runnable() {
@Override
public void run() {
if (popupInfo == null) return;
if (isRTL) {
translationX = isShowLeft ? -(XPopupUtils.getAppWidth(getContext()) - rect.left - getPopupContentView().getMeasuredWidth() - defaultOffsetX)
: -(XPopupUtils.getAppWidth(getContext()) - rect.right + defaultOffsetX);
} else {
translationX = isShowLeft ? (rect.left + defaultOffsetX) : (rect.right - getPopupContentView().getMeasuredWidth() - defaultOffsetX);
}
if (popupInfo.isCenterHorizontal) {
//水平居中
if (isShowLeft)
if (isRTL) {
translationX -= (rect.width() - getPopupContentView().getMeasuredWidth()) / 2f;
} else {
translationX += (rect.width() - getPopupContentView().getMeasuredWidth()) / 2f;
}
else {
if (isRTL) {
translationX += (rect.width() - getPopupContentView().getMeasuredWidth()) / 2f;
} else {
translationX -= (rect.width() - getPopupContentView().getMeasuredWidth()) / 2f;
}
}
}
if (isShowUpToTarget()) {
//说明上面的空间比较大,应显示在atView上方
// translationX: 在左边就和atView左边对齐,在右边就和其右边对齐
translationY = rect.top - getPopupContentView().getMeasuredHeight() - defaultOffsetY;
} else {
translationY = rect.bottom + defaultOffsetY;
}
//
getPopupContentView().setTranslationX(translationX);
getPopupContentView().setTranslationY(translationY);
initAndStartAnimation();
}
});
}
}
public Rect getAtViewRect() {
int[] locations = new int[2];
popupInfo.atView.getLocationOnScreen(locations);
return new Rect(locations[0], locations[1], locations[0] + popupInfo.atView.getMeasuredWidth(),
locations[1] + popupInfo.atView.getMeasuredHeight());
}
同样遇到这个问题,XPopup的版本号是2.9.19,按照楼主的方式重写,位置一样是偏移的
同样遇到这个问题,XPopup的版本号是2.9.19,按照楼主的方式重写,位置一样是偏移的
这个问题解决了吗?我也遇到同样的问题!
我使用的版本是2.9.11 这个版本用我的代码在弹窗中使用没有问题 其他版本没有进行测试
同样遇到这个问题,XPopup的版本号是2.9.19,按照楼主的方式重写,位置一样是偏移的
这个问题解决了吗?我也遇到同样的问题!
我的解决方式是自己重新计算控件在屏幕的位置,然后把坐标传进去
getLocationInWindow
1、设置dialog 全屏 dialog?.window?.apply { // 获取对话框的窗口参数 val params = attributes // 设置宽度和高度为全屏 params.width = WindowManager.LayoutParams.MATCH_PARENT params.height = WindowManager.LayoutParams.MATCH_PARENT // 将窗口参数应用于对话框 attributes = params }
2、getLocationOnScreen 设置attouchview避免走atview获取getLocationInWindow
https://github.com/li-xiaojun/XPopup/issues/954#issue-1230871696 中已经解决了这个问题 但是 我查看到因为 为了修复 修复横屏时Attach系列弹窗位置不对的问题 这个bug导致问题重新出现 建议新增可供选择使用的方法来处理这个问题