在Android中,我可以获取视图相对于Activity根布局的x和y位置吗?
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;
这里是文档
这是一种解决方案,但由于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
来实现它。
请使用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
方法获取这些值。 - Xander int[] img_coordinates = new int[2];
接着在你的父布局上加入ViewTreeObserver
,以获取布局膨胀的回调,然后再获取视图位置 否则你将得到错误的x和y坐标
// 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];
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;
}
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;
我刚刚在这里找到答案
它说: 可以通过调用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
private int getRelativeTop(View view) {
final View parent = (View) view.getParent();
int[] parentLocation = new int[2];
int[] viewLocation = new int[2];
view.getLocationOnScreen(viewLocation);
parent.getLocationOnScreen(parentLocation);
return viewLocation[1] - parentLocation[1];
}
timeIndicator.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
final int relativeTop = getRelativeTop(timeIndicator);
});
parentViewGroup
可以是视图层次结构中的任何一个父级,因此对于 ScrollView 也可以完美使用。 - Sira Lam