i_am_jorf
i_am_jorf

Reputation: 54630

What is the android equivalent of UIView's convertRect / convertPoint functions?

UIView has the following:

- convertPoint:toView:
- convertPoint:fromView:
- convertRect:toView:
- convertRect:fromView:

What is the Android equivalent? More generally, given two Views, how do I get the second View's rect in the coordinate system of the first?

Upvotes: 14

Views: 3665

Answers (3)

milez
milez

Reputation: 2201

The way to do this is with getGlobalVisibleRect(Rect r, Point globalOffset).

/**
 * If some part of this view is not clipped by any of its parents, then
 * return that area in r in global (root) coordinates. To convert r to local
 * coordinates (without taking possible View rotations into account), offset
 * it by -globalOffset (e.g. r.offset(-globalOffset.x, -globalOffset.y)).
 * If the view is completely clipped or translated out, return false.
 *
 * @param r If true is returned, r holds the global coordinates of the
 *        visible portion of this view.
 * @param globalOffset If true is returned, globalOffset holds the dx,dy
 *        between this view and its root. globalOffet may be null.
 * @return true if r is non-empty (i.e. part of the view is visible at the
 *         root level.
 */

So you give it a Point and get the offset relative to the root View. They key is that your views get a location relative to a common item. You can then use this offset to calculate relative positions. The doc says to get local coordinates, you offset the Rect with -globalOffset. If you want to get the second view's Rect in coordinates of the first, then offset the Rect of the first view with -globalOffset of the second view.

Similarly, you can use the globalOffset to transform a point to relative coordinates if you know it's coordinates in the root view. This should be a subtraction: anyPoint - globalOffset.

Remember to check that getGlobalVisibleRect() returned true and that globalOffset is not null before you do the calculations.

Upvotes: 0

Sruit A.Suk
Sruit A.Suk

Reputation: 7273

In Android it might not have the method that exactly like that

however, you could do by

View.getLocationOnScreen(int[] location) and View.getLocationInWindowint[] location()

which

getLocationOnScreen(int[] location)

Computes the coordinates of this view in its window.

getLocationInWindow(int[] location)

Computes the coordinates of this view on the screen.


or View.getLeft() and View.getTop()

which

getLeft()

Left position of this view relative to its parent.

getTop()

Top position of this view relative to its parent.


for you case, I would use getLeft() and getTop() to find it's space between 2 View and get range of it

this link has an example of how to find it using getLeft() and getTop()

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());
}

Upvotes: 0

tachyonflux
tachyonflux

Reputation: 20221

I don't think there is an equivalent as part of the sdk, but it seems like you could write your own implementation very easily using getLocationOnScreen:

public static Point convertPoint(Point fromPoint, View fromView, View toView){
    int[] fromCoord = new int[2];
    int[] toCoord = new int[2];
    fromView.getLocationOnScreen(fromCoord);
    toView.getLocationOnScreen(toCoord);

    Point toPoint = new Point(fromCoord[0] - toCoord[0] + fromPoint.x,
            fromCoord[1] - toCoord[1] + fromPoint.y);

    return toPoint;
}

public static Rect convertRect(Rect fromRect, View fromView, View toView){
    int[] fromCoord = new int[2];
    int[] toCoord = new int[2];
    fromView.getLocationOnScreen(fromCoord);
    toView.getLocationOnScreen(toCoord);

    int xShift = fromCoord[0] - toCoord[0];
    int yShift = fromCoord[1] - toCoord[1];

    Rect toRect = new Rect(fromRect.left + xShift, fromRect.top + yShift,
            fromRect.right + xShift, fromRect.bottom + yShift);

    return toRect;
}

Upvotes: 22

Related Questions