我的 Android 应用有一个带有标记的游戏地图。当用户点击一个标记时,我会显示一个与地图标记对齐的 PopupWindow(类似于 Google 地图)。我遇到的问题是,如果标记靠近屏幕顶部,则 PopupWindow 与 ActionBar 重叠(如果标记足够高,则在状态栏下方)。
我通过调用 showAtLocation() 来显示 PopupWindow,我希望这会将视图限制在“地图”片段内部(它在左侧和右侧),但这不起作用。
我已经实施了一项调整,以考虑弹出窗口内的文本占用多行,我在布局视图后更新弹出窗口的 Y 位置。这没有问题,但是当我尝试为这种情况添加另一个垂直调整时,PopupWindow 的位置不会改变。
这是 PopupWindow 实现的代码:
/**
* Displays a PopupWindow.
*/
public class MyPopupWindow extends PopupWindow
{
private Fragment m_fragment;
private int m_x;
private int m_y;
/**
* Displays a PopupWindow at a certain offset (x, y) from the center of fragment's view.
*/
public static MyPopupWindow createPopup (Context context, Fragment fragment, int x, int y)
{
// Create the PopupWindow's content view
LayoutInflater inflater = LayoutInflater.from (context);
View popupView = inflater.inflate (R.layout.view_map_popup, null);
MyPopupWindow popupWindow = new MyPopupWindow (popupView, x, y);
popupWindow.m_fragment = fragment;
popupWindow.showAtLocation (fragment.getView (), Gravity.CENTER, x, y);
return popupWindow;
}
private MyPopupWindow (View view, int x, int y)
{
super (view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
m_x = x;
m_y = y;
TextView title = (TextView) view.findViewById (R.id.lblMapPopupTitle);
title.setText ("Exercise Title");
TextView description = (TextView) view.findViewById (R.id.lblMapPopupDescription);
description.setText ("Exercise Description\nSecond Line\nThird Line\nFourth Line\nAnd one more...");
view.setVisibility (View.INVISIBLE);
view.addOnLayoutChangeListener (layoutChangeListener);
}
// If the tapped map location is too close to the edge, determine the
// delta-x and delta-y needed to align it with the PopupWindow
private int getHorizontalAdjustment (int popupWidth)
{
int horizontalAdjustment = 0;
int parentWidth = m_fragment.getView ().getWidth ();
if ((parentWidth / 2) + m_x + (popupWidth / 2) > parentWidth)
{
horizontalAdjustment = parentWidth - ((parentWidth / 2) + m_x + (popupWidth / 2));
}
else if ((parentWidth / 2) + m_x - (popupWidth / 2) < 0)
{
horizontalAdjustment = 0 - ((parentWidth / 2) + m_x - (popupWidth / 2));
}
return horizontalAdjustment;
}
private int getVerticalAdjustment (int popupHeight)
{
int verticalAdjustment = 0;
int parentHeight = m_fragment.getView ().getHeight ();
int y = m_y - (popupHeight / 2);
if ((parentHeight / 2) + y + (popupHeight / 2) > parentHeight)
{
verticalAdjustment = parentHeight - ((parentHeight / 2) + y + (popupHeight / 2));
}
else if ((parentHeight / 2) + y - (popupHeight / 2) < 20)
{
verticalAdjustment = 20 - ((parentHeight / 2) + y - (popupHeight / 2));
}
return verticalAdjustment;
}
private View.OnLayoutChangeListener layoutChangeListener = new View.OnLayoutChangeListener ()
{
@Override
public void onLayoutChange (View view, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom)
{
int height = bottom - top;
int width = right - left;
// Adjust the y-position for the inflated height of the view
// (so the popup's bottom edge lines up with the tapped marker's top edge)
int y = m_y - (height / 2);
int x = m_x;
// Determine any adjustments that need to be made to line up the tapped marker with the popup
int horizontalAdjustment = getHorizontalAdjustment (width);
int verticalAdjustment = getVerticalAdjustment (height);
y -= verticalAdjustment;
// Update our position with the re-calculated position
update (x, y, -1, -1);
view.setVisibility (View.VISIBLE);
}
};
}
该问题可以在此屏幕截图中看到:PopupWindow 与 ActionBar 重叠
基本上,我需要 (1) 让 PopupWindow 剪辑到 Fragment 的视图而不与 ActionBar 重叠,或者 (2) 让 PopupWindow 在它与 ActionBar 重叠的情况下更新其位置。
任何帮助是极大的赞赏。