获取相对于根布局的View坐标

fhu*_*cho 130 android coordinates android-layout

我可以获取相对于Android中我的Activity的根布局的View的x和y位置吗?

ram*_*jan 135

这是一种解决方案,但由于API会随着时间的推移而发生变化,并且可能还有其他方法,因此请务必查看其他答案.一个声称更快,另一个声称更容易.

private int getRelativeLeft(View myView) {
    if (myView.getParent() == myView.getRootView())
        return myView.getLeft();
    else
        return myView.getLeft() + getRelativeLeft((View) myView.getParent());
}

private int getRelativeTop(View myView) {
    if (myView.getParent() == myView.getRootView())
        return myView.getTop();
    else
        return myView.getTop() + getRelativeTop((View) myView.getParent());
}
Run Code Online (Sandbox Code Playgroud)

如果有效,请告诉我.

它应该递归地添加每个父容器的顶部和左侧位置.您也可以使用Pointif 实现它.

  • android api已经为root提供了相对坐标.看这里http://stackoverflow.com/a/36740277/2008214 (3认同)

car*_*eli 134

Android API已经提供了实现这一目标的方法.试试这个:

Rect offsetViewBounds = new Rect();
//returns the visible bounds
childView.getDrawingRect(offsetViewBounds);
// calculates the relative coordinates to the parent
parentViewGroup.offsetDescendantRectToMyCoords(childView, offsetViewBounds); 

int relativeTop = offsetViewBounds.top;
int relativeLeft = offsetViewBounds.left;
Run Code Online (Sandbox Code Playgroud)

这是文档

  • 这应该是公认的答案.没有堆栈溢出的可能性,也没有数学错误的可能性.谢谢! (14认同)
  • 效果很好,只是想提一下,`parentViewGroup` 可以是视图层次结构中的任何父级,因此它也适用于 ScrollView。 (2认同)

小智 91

请使用view.getLocationOnScreen(int[] location);(参见Javadocs).答案是整数数组(x = location[0]和y = location[1]).

  • 还有View.getLocationInWindow(int []),它返回视图相对于窗口的位置. (10认同)
  • 这将返回屏幕的位置而不是Activity的根布局. (9认同)
  • 要获取相对于根布局的位置,只需为根布局和元素调用getLocationInWindow,并使用减法的力量.它比接受的答案更简单,更快. (6认同)
  • 但这在滚动视图中不起作用. (3认同)

Tal*_*alL 36

无需手动计算.

只需像这样使用getGlobalVisibleRect:

Rect myViewRect = new Rect();
myView.getGlobalVisibleRect(myViewRect);
float x = myViewRect.left;
float y = myViewRect.top;
Run Code Online (Sandbox Code Playgroud)

另请注意,对于中心坐标,而不是:

...
float two = (float) 2
float cx = myViewRect.left + myView.getWidth() / two;
float cy = myViewRect.top + myView.getHeight() / two;
Run Code Online (Sandbox Code Playgroud)

你可以这样做:

float cx = myViewRect.exactCenterX();
float cy = myViewRect.exactCenterY();
Run Code Online (Sandbox Code Playgroud)

  • 就像使用`getLocationOnScreen`的答案一样,也许这个答案可以编辑,以便更容易使用和理解?通常单行答案并不理想. (9认同)
  • 这应该是接受的答案.getLocationOnScreen和getGlobalVisibleRect一样有效.但是getGlobalVisibleRect提供了更多的信息,并且不需要使用原始数组.因此我会选择getGlobalVisibleRect.用法很简单.Rect positionRect = new Rect(); view.getGlobablVisibleRect(positionRect); // x = positionRect.left // y = positionRect.top.干杯 (2认同)

Ker*_*ter 32

View rootLayout = view.getRootView().findViewById(android.R.id.content);

int[] viewLocation = new int[2]; 
view.getLocationInWindow(viewLocation);

int[] rootLocation = new int[2];
rootLayout.getLocationInWindow(rootLocation);

int relativeLeft = viewLocation[0] - rootLocation[0];
int relativeTop  = viewLocation[1] - rootLocation[1];
Run Code Online (Sandbox Code Playgroud)

首先,我获得根布局,然后计算与视图的坐标差异.
您也可以使用getLocationOnScreen()而不是getLocationInWindow().

  • 视图是缩放和旋转的是什么? (2认同)

Hit*_*ahu 7

你可以用`

view.getLocationOnScreen(int [] location)

;`正确获取视图的位置.

但有一个捕获如果你使用它之前的布局已经膨胀,你会得到错误的位置.

解决这个问题的方法是这样添加ViewTreeObserver: -

全局声明数组以存储视图的xy位置

 int[] img_coordinates = new int[2];
Run Code Online (Sandbox Code Playgroud)

然后添加ViewTreeObserver你的父布局来获得布局膨胀的回调,然后才获取视图的位置,否则你会得到错误的xy坐标

  // set a global layout listener which will be called when the layout pass is completed and the view is drawn
            parentViewGroup.getViewTreeObserver().addOnGlobalLayoutListener(
                    new ViewTreeObserver.OnGlobalLayoutListener() {
                        public void onGlobalLayout() {
                            //Remove the listener before proceeding
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                                parentViewGroup.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                            } else {
                                parentViewGroup.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                            }

                            // measure your views here
                            fab.getLocationOnScreen(img_coordinates);
                        }
                    }
            );
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它

xposition = img_coordinates[0];
yposition =  img_coordinates[1];
Run Code Online (Sandbox Code Playgroud)