如何在ViewPager中正确获取子View在屏幕上的实际坐标
解决ViewPager中获取子View坐标偏移问题
偏差原因
getLocationOnScreen获取的是View相对于系统屏幕的绝对坐标。ViewPager默认会预加载相邻页面,将不在当前可视区域的页面内容绘制在屏幕外,所以非第一页的子View坐标会叠加整页宽度的偏移量,就是你遇到的坐标异常问题。
修复方案
只需要在原有获取坐标的逻辑基础上,减去当前ViewPager的scrollX值(即ViewPager横向滚动过的像素总数),就能得到子View在当前可见页面内的真实坐标。
示例代码
int[] location = new int[2]; childView.getLocationOnScreen(location); // 查找子View所属的ViewPager实例,已知实例可直接赋值 ViewPager viewPager = findParentViewPager(childView); if (viewPager != null) { // 减去横向滚动偏移得到真实X坐标,Y轴无横向偏移无需修改 int realX = location[0] - viewPager.getScrollX(); int realY = location[1]; }
嵌套层级查找ViewPager的工具方法
如果子View和ViewPager之间有多层布局嵌套,可通过如下方法向上递归查找:
private ViewPager findParentViewPager(View child) { if (child == null) return null; ViewParent parent = child.getParent(); while (parent != null && parent instanceof View) { if (parent instanceof ViewPager) { return (ViewPager) parent; } parent = ((View) parent).getParent(); } return null; }
验证逻辑
你的场景中:
- 第一页ViewPager的
scrollX为0,15-0=15符合预期 - 第二页
scrollX为1080,1095-1080=15符合预期 - 第三页
scrollX为2160,2175-2160=15符合预期
注意事项
- 如果ViewPager上层还有可横向滚动的父容器,需要将所有上层父容器的横向滚动偏移量一同扣除
- 如果你使用的是ViewPager2,逻辑完全一致,直接获取ViewPager2的
scrollX值扣除即可
内容的提问来源于stack exchange,提问作者user1695123
相关产品推荐
相关产品推荐

