返回

PopupWindow悬浮于ScrollView,随View而动

Android

在ScrollView中创建悬浮于指定View上方的PopupWindow

理解问题

在Android应用程序中,ScrollView是一个用于在垂直方向上滚动内容的布局容器。当需要在ScrollView内弹出PopupWindow时,通常希望PopupWindow能够悬浮于指定View上方,并跟随View滚动。然而,默认情况下,PopupWindow不会跟随ScrollView的滚动而移动。本文将深入探讨这一问题,并提供一种简单实用的解决方案。

定制PopupWindow

要理解为什么PopupWindow不会跟随ScrollView滚动,我们需要了解PopupWindow的本质。PopupWindow是一个独立的窗口,与ScrollView的滚动机制无关。当ScrollView滚动时,PopupWindow的位置不会自动更新。

为了解决此问题,我们需要创建一个自定义PopupWindow,并使用监听器来跟踪ScrollView的滚动事件。每当ScrollView滚动时,监听器会更新PopupWindow的位置,使其始终悬浮于指定View上方。

实现步骤

以下是在ScrollView中实现PopupWindow悬浮于指定View上方的步骤:

  1. 创建自定义PopupWindow
public class CustomPopupWindow extends PopupWindow {

    private View anchorView;

    public CustomPopupWindow(View anchorView) {
        super(context);
        this.anchorView = anchorView;
    }

    @Override
    public void showAtLocation(View parent, int gravity, int x, int y) {
        super.showAtLocation(parent, gravity, x, y);
        updatePosition();
    }

    private void updatePosition() {
        int[] location = new int[2];
        anchorView.getLocationOnScreen(location);
        update(location[0], location[1] - getHeight(), -1, -1);
    }
}
  1. 在ScrollView中创建PopupWindow
ScrollView scrollView = findViewById(R.id.scrollView);
View anchorView = findViewById(R.id.anchorView);

CustomPopupWindow popupWindow = new CustomPopupWindow(anchorView);
// ... 设置PopupWindow的内容和样式 ...

scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
    @Override
    public void onScrollChanged() {
        popupWindow.updatePosition();
    }
});

示例代码

import android.app.Activity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.PopupWindow;
import android.widget.ScrollView;
import android.widget.TextView;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ScrollView scrollView = findViewById(R.id.scrollView);
        TextView anchorView = findViewById(R.id.anchorView);

        // 创建自定义PopupWindow
        CustomPopupWindow popupWindow = new CustomPopupWindow(anchorView);
        popupWindow.setContentView(R.layout.popup_window);

        // 在ScrollView中创建PopupWindow
        scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
            @Override
            public void onScrollChanged() {
                popupWindow.updatePosition();
            }
        });

        // 显示PopupWindow
        popupWindow.showAtLocation(scrollView, Gravity.TOP | Gravity.START, 0, 0);
    }
}

结论

通过使用自定义PopupWindow和ScrollView的滚动监听器,我们可以轻松实现PopupWindow悬浮于ScrollView内指定View上方并跟随View滚动。这种方法简单易懂,适用于各种场景。

常见问题解答

  1. 为什么默认情况下PopupWindow不会跟随ScrollView滚动?

    • 因为PopupWindow是一个独立的窗口,与ScrollView的滚动机制无关。
  2. 如何创建一个悬浮于指定View上方的PopupWindow?

    • 使用本文中提供的自定义PopupWindow类,并使用ScrollView的滚动监听器更新PopupWindow的位置。
  3. 如何获得指定View的位置?

    • 使用View.getLocationOnScreen()方法获取View在屏幕上的位置。
  4. 如何更新PopupWindow的位置?

    • 使用PopupWindow.update()方法更新PopupWindow的位置。
  5. 示例代码中的代码有什么作用?

    • 示例代码创建了一个自定义PopupWindow,并在ScrollView中显示它。滚动ScrollView时,PopupWindow将跟随指定的View移动。