遇到这样一个需求:根布局为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的位置。
- 首先定义变量来保存PopupWindow的初始位置和大小
private int orginalX, originalY;
private int popWidth, popHeight;
- 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运行即可。
今天的文章ScrollView里面基于某个View弹出PopupWindow,PopupWindow不会跟着View滚动?分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/20704.html