获取视图的相对于根布局的坐标

我可以得到一个视图的X和Y位置相对于我的活动在Android的根布局?

这是一个解决scheme,但是由于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()); } 

让我知道这是否有效。

它应该recursion地添加每个父容器的顶部和左侧位置。 如果你愿意,你也可以用Point实现它。

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

不需要手动计算。

只要像这样使用getGlobalVisibleRect :

 Rect myViewRect = new Rect(); myView.getGlobalVisibleRect(myViewRect); float x = myViewRect.left; float y = myViewRect.top; 

还要注意,对于中心坐标,而不是像:

 ... float two = (float) 2 float cx = myViewRect.left + myView.getWidth() / two; float cy = myViewRect.top + myView.getHeight() / two; 

你可以做:

 float cx = myViewRect.exactCenterX(); float cy = myViewRect.exactCenterY(); 
 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]; 

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

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; 

这是文档

你可以使用`

view.getLocationOnScreen(int [] location)

;`正确地获取你的视图的位置。

但是如果你在布局被夸大之前使用它,你会得到错误的位置。

解决这个问题的办法是像这样添加ViewTreeObserver : –

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

  int[] img_coordinates = new int[2]; 

然后添加ViewTreeObserver在您的父级布局来获得布局膨胀的callback,只有然后取景的位置, 否则你会得到错误的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); } } ); 

然后像这样使用它

 xposition = img_coordinates[0]; yposition = img_coordinates[1]; 

我刚在这里find了答案

它说:可以通过调用方法getLeft()和getTop()来检索视图的位置。 前者返回表示视图的矩形的左边或X坐标。 后者返回表示视图的矩形的顶部或Y坐标。 这些方法都返回相对于其父的视图的位置。 例如,当getLeft()返回20时,这意味着该视图位于其直接父级左边缘右侧20个像素。

所以使用:

 view.getLeft(); // to get the location of X from left to right view.getRight()+; // to get the location of Y from right to left 

因为有人仍然试图弄清楚这一点。 这就是你如何获得view的中心X和Y.

  int pos[] = new int[2]; view.getLocationOnScreen(pos); int centerX = pos[0] + view.getMeasuredWidth() / 2; int centerY = pos[1] + view.getMeasuredHeight() / 2; 

我自己写了两个效用方法,似乎在大多数情况下工作,处理滚动,平移和缩放,而不是旋转。 我尝试在框架中使用offsetDescendantRectToMyCoords()之后做了这个,它的准确性不一致。 它在某些情况下起作用,但在其他情况下给出错误结果

“point”是具有两个元素(x和y坐标)的浮点数组,“祖先”是树层次结构中“后代”上方的视图组。

首先从后代坐标到祖先的方法:

 public static void transformToAncestor(float[] point, final View ancestor, final View descendant) { final float scrollX = descendant.getScrollX(); final float scrollY = descendant.getScrollY(); final float left = descendant.getLeft(); final float top = descendant.getTop(); final float px = descendant.getPivotX(); final float py = descendant.getPivotY(); final float tx = descendant.getTranslationX(); final float ty = descendant.getTranslationY(); final float sx = descendant.getScaleX(); final float sy = descendant.getScaleY(); point[0] = left + px + (point[0] - px) * sx + tx - scrollX; point[1] = top + py + (point[1] - py) * sy + ty - scrollY; ViewParent parent = descendant.getParent(); if (descendant != ancestor && parent != ancestor && parent instanceof View) { transformToAncestor(point, ancestor, (View) parent); } } 

接下来,从祖先到后代,

 public static void transformToDescendant(float[] point, final View ancestor, final View descendant) { ViewParent parent = descendant.getParent(); if (descendant != ancestor && parent != ancestor && parent instanceof View) { transformToDescendant(point, ancestor, (View) parent); } final float scrollX = descendant.getScrollX(); final float scrollY = descendant.getScrollY(); final float left = descendant.getLeft(); final float top = descendant.getTop(); final float px = descendant.getPivotX(); final float py = descendant.getPivotY(); final float tx = descendant.getTranslationX(); final float ty = descendant.getTranslationY(); final float sx = descendant.getScaleX(); final float sy = descendant.getScaleY(); point[0] = px + (point[0] + scrollX - left - tx - px) / sx; point[1] = py + (point[1] + scrollY - top - ty - py) / sy; }