ScrollView里面基于某个View弹出PopupWindow,PopupWindow不会跟着View滚动?

遇到这样一个需求:根布局为ScrollView,内部有一个TextView,叫它A,需要在A正上方弹出一个PopupWindow。 初看其实很简单,根据A的位置和大小,算出PopupWindow的位置,调用showAtLocation方法即可实现在A正上方弹出。 代码如下:

showPopAlongView(textView);
private void showPopAlongView(View v) {
        View view = View.inflate(this, R.layout.pop_layout, null);
        view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
        int measureHeight = view.getMeasuredHeight();
        int measureWidth = view.getMeasuredWidth();
        PopupWindow popupWindow = new PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        popupWindow.setFocusable(false);
        popupWindow.setBackgroundDrawable(new ColorDrawable(0x00000000));
        popupWindow.setOutsideTouchable(false);
        int[] location = new int[2];
        v.getLocationOnScreen(location);
        popupWindow.showAtLocation(v, Gravity.NO_GRAVITY, location[0] + v.getMeasuredWidth() / 2 - measureWidth / 2, location[1] - measureHeight);
    }

如上,就可以在textView正上方显示出一个PopupWindow。看起来一切都好,但是当ScrollView开始上下滚动的时候,就有问题了:

这里写图片描述

可以发现,我们的PopupWindow并没有跟随一起滚动,这是因为在调用showAtLocation的时候,PopupWindow的位置已经确定了,所以并不会跟着A的滚动而滚动。 这样的效果产品经理肯定不会同意的,所以就需要我们来动态更新PopupWindow的位置了。 来看PopupWindow的一个方法:

    /**
     * Updates the position and the dimension of the popup window.
     * <p>
     * Width and height can be set to -1 to update location only. Calling this
     * function also updates the window with the current popup state as
     * described for {@link #update()}.
     *
     * @param x the new x location
     * @param y the new y location
     * @param width the new width in pixels, must be >= 0 or -1 to ignore
     * @param height the new height in pixels, must be >= 0 or -1 to ignore
     */
    public void update(int x, int y, int width, int height) {
        update(x, y, width, height, false);
    }

用这个方法可以更新PopupWindow的尺寸和位置。我们这里只需要让PopupWindow始终在A的正上方,所以重点就是确定随着ScrollView的滚动PopupWindow的位置。

  1. 首先定义变量来保存PopupWindow的初始位置和大小
    private int orginalX, originalY;

    private int popWidth, popHeight;
  1. ScrollView设置滚动监听,计算出PopupWindow新的y坐标,调用update方法更新。
    scrollView.setOnScrollChangeListener(this);
    /**
     * Called when the scroll position of a view changes.
     *
     * @param v          The view whose scroll position has changed.
     * @param scrollX    Current horizontal scroll origin.
     * @param scrollY    Current vertical scroll origin.
     * @param oldScrollX Previous horizontal scroll origin.
     * @param oldScrollY Previous vertical scroll origin.
     */
    @Override
    public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
        int currentY = originalY - scrollY;
        popupWindow.update(orginalX, currentY, popWidth, popHeight);
    }

没错,步骤就是这么简单,然后看下效果:

这里写图片描述

可以看出,已经基本满足最开始的需求了。不过好像还有点儿问题,滚动的时候PopupWindow与A之间会有白色空隙,暂时还没有找到原因,有知道的朋友欢迎留言。

完整代码地址 选择moudle:scrollviewwithpopwindow运行即可。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏郭霖

Android 3D滑动菜单完全解析,实现推拉门式的立体特效

在上一篇文章中,我们学习了Camera的基本用法,并借助它们编写了一个例子,实现了类似于API Demos里的图片中轴旋转功能。不过那个例子的核心代码是来自于A...

33610
来自专栏Android干货园

高仿微信朋友圈评论popwindow

版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/lyhhj/article/details/47...

2061
来自专栏向治洪

android自定义view实现progressbar的效果

一键清理是很多Launcher都会带有的功能,其效果也比较美观。实现方式也许有很多中,其中常见的是使用图片drawable来完成的,具体可以参考这篇文章:模仿实...

2765
来自专栏Android知识点总结

4-VIV-Android之PopupWindow

1192
来自专栏Android干货

Android项目实战(四十七):轮播图效果Viewpager

2689
来自专栏7号代码

Android应用界面开发——ListView,GridView,ScrollView

ListView的意思是列表视图,是应用最广泛的一种视图,例如联系人,功能列表,菜单等等都会用到ListView。

1003
来自专栏向治洪

listview滑动删除

今天还是给大家带来自定义控件的编写,自定义一个ListView的左右滑动删除Item的效果,这个效果之前已经实现过了,有兴趣的可以看下Android 使用Scr...

2477
来自专栏Android干货

Android项目实战(七):Dialog主题Activity实现自定义对话框效果

3878
来自专栏androidBlog

自定义View常用例子二(点击展开隐藏控件,九宫格图片控件)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gdutxiaoxu/article/details/...

1031
来自专栏Android源码框架分析

三句代码创建全屏Dialog或者DialogFragment:带你从源码角度实现全屏Dialog

Dialog是APP开发中常用的控件,同Activity类似,拥有独立的Window窗口,但是Dialog跟Activity还是有一定区别的,最明显的就是:默认...

3404

扫码关注云+社区

领取腾讯云代金券