How to set the four parameters of View.layout(l, t, r, b)

Neoh picture Neoh · May 6, 2013 · Viewed 7.4k times · Source

I am facing the same problem in this question, but I have difficulty in understanding the exact meaning of the four position parameters in layout(int l, int t, int r, int b). I know they represent left, top, right and bottom respectively relative to parent, but "relative" to where exactly?

For example, if I translate the button down 100 pixel, in order to move the clickable area down 100 pixel should I set

//            l   t   r   b
button.layout(0, 100, 0, button.getHeight()+100)

? Does the integer 100 of second parameter mean 100 pixel down relative to the top of parent? Is the fourth parameter means button.getHeight()+100 relative to the top of parent also??? I tested on my device, the clickable area does not move down as I want. I'm very confused here, any help is greatly appreciated.

Answer

adamp picture adamp · May 6, 2013

The parameters to layout are relative to the parent view's upper left corner. X increases as you move to the right and Y increases as you move down. It is not relative to the view's current position.

You probably don't want to call layout on a child view outside of its parent's onLayout method. There are several other bits of internal bookkeeping that happen as a result of calling layout that will change internal state in a way you don't want for simple animations.

Typically layout is called like this:

child.layout(x, y, x + child.getMeasuredWidth(), y + child.getMeasuredHeight());

The parameters are absolute, with (0, 0) at the parent's upper left corner.

But if you're simply moving a view around for animation you probably want to do something more like:

// Adjust horizontally; dx = change in x position
child.offsetLeftAndRight(dx);

// Adjust vertically; dy = change in y position
child.offsetTopAndBottom(dy);

The parameters to the offset* methods are relative to the view's current position.

If you write a ViewGroup class that moves its child views around in this way, remember that you can get a layout request at any time. At that point your ViewGroup's onLayout method will try to position the child based on its usual layout rules and it will need to adjust this positioning to reflect any other accumulated movement you want to preserve.