0

I have a simple problem. I'm extending ViewGroup, and I want to align buttons to the right side of the screen from top-to-bottom. Problem is, nothing shows up on my screen. I've confirmed it's not a problem with anything else, only my onLayout() overriden method. Could you help me out?

Code in question:

    final int count = getChildCount();
    int curWidth, curHeight, curLeft, curTop;

    //get the available size of child view
    int childLeft = this.getPaddingLeft();
    int childTop = this.getPaddingTop();
    int childRight = this.getMeasuredWidth() - this.getPaddingRight();
    int childBottom = this.getMeasuredHeight() - this.getPaddingBottom();
    int childWidth = childRight - childLeft;
    int childHeight = childBottom - childTop;

    curTop = childTop;
    for (int i = 0; i < count; i++) {
        View child = getChildAt(i);

        //Get the maximum size of the child
        child.measure(MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.AT_MOST),
                MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.AT_MOST));
        curWidth = child.getMeasuredWidth();
        curHeight = child.getMeasuredHeight();

        child.layout(getMeasuredWidth() - getPaddingRight() - curWidth,
                curTop, getMeasuredWidth() - getPaddingRight(), curTop - curHeight);
        curTop -= childHeight;
    }

I've added a few LOG statements to my code, and what I have is frankly infuriating.

07-11 14:46:46.321  32172-32172/milespeele.canvas D/Miles﹕ LEFT: 912
07-11 14:46:46.322  32172-32172/milespeele.canvas D/Miles﹕ TOP: 1008
07-11 14:46:46.322  32172-32172/milespeele.canvas D/Miles﹕ RIGHT: 1080
07-11 14:46:46.322  32172-32172/milespeele.canvas D/Miles﹕ BOTTOM: 1008

These are all valid coordinates (for one button) given the dimensions of my phone's creen, but no buttons are appearing.

3 Answers 3

1

I didn't scan this completely, but I see you have curTop - curHeight as last parameter in child.layout(). Should it be curTop + curHeight?

1
  • That doesn't work either. I wanted to increment vertically, so the top of the current child is just the last currentTop - that child's height. Commented Jul 11, 2015 at 18:32
1

You are decrementing curTop. Coordinate values increase going down the screen, so you are actually layout out children off screen above the top of the ViewGroup. I think you want curTop + curHeight as the last argument of child.layout(), and i think the last line should be curTop += curHeight.

As an aside, you really should not be measuring children in onLayout(). That's what onMeasure() is for.

1
  • Right, I'll fix that quirk once I get the children to actually appear on the screen. Incrementing curTop does nothing, sadly. Children are still of the screen. Commented Jul 11, 2015 at 18:35
0

Solved. Thanks for those that answered.

It seemed the problem was I misunderstood android's coordinate system.

Working code: (where l & r are parameters of onLayout())

    final int count = getChildCount();

    int left = (int) (l + getMeasuredWidth() - buttonMargin - buttonWidth);
    int right = (int) (r - buttonMargin);

    int currentTop = (int) (t + buttonMargin);
    for (int i = 0; i < count; i++) {
        View child = getChildAt(i);
        child.layout(left, currentTop, right, currentTop + buttonHeight);
        currentTop += buttonHeight + buttonMargin;
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.