Answers:
这是一个解决方案,尽管由于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());
}
让我知道是否可行。
它应该以递归方式添加每个父容器的顶部和左侧位置。如果需要,也可以使用实现它Point
。
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;
这是文档
parentViewGroup
可以是视图层次结构中的任何父级,因此它也非常适合ScrollView。
请使用view.getLocationOnScreen(int[] location);
(请参阅Javadocs)。答案在整数数组(x = location[0]
和y = location[1]
)中。
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()
。
无需手动计算。
像这样使用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();
getGlobalVisibleRect
操作是, globalOffset.set(-mScrollX, -mScrollY);
因此getScollX/Y
如果您只需要相对coodinates,就可以获取这些值。
您可以使用`
view.getLocationOnScreen(int []位置)
;`以正确获取视图的位置。
但有一个捕获如果你使用它之前的布局已经膨胀,你会得到错误的位置。
解决此问题的方法是这样添加的ViewTreeObserver
:-
全局声明数组以存储视图的xy位置
int[] img_coordinates = new int[2];
然后添加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);
}
}
);
然后像这样使用它
xposition = img_coordinates[0];
yposition = img_coordinates[1];
我为自己编写了两个似乎在大多数情况下都可以使用的实用程序方法,即处理滚动,平移和缩放,但不适用于旋转。我在尝试在框架中使用offsetDescendantRectToMyCoords()后执行了此操作,该框架的准确性不一致。它在某些情况下有效,但在其他情况下却给出错误的结果。
“点”是具有两个元素(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;
}
如果有人仍在设法解决这个问题。这就是您获得的中心X和Y的方式view
。
int pos[] = new int[2];
view.getLocationOnScreen(pos);
int centerX = pos[0] + view.getMeasuredWidth() / 2;
int centerY = pos[1] + view.getMeasuredHeight() / 2;
我刚刚在这里找到答案
它说:可以通过调用方法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