获取视图的相对于根布局的坐标
我可以得到一个视图的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; }