2

我的 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 重叠的情况下更新其位置

任何帮助是极大的赞赏。

4

0 回答 0