Zennichimaro
Zennichimaro

Reputation: 5306

Android - how to set position of children view in onLayout

How do we set the position of subview in Android?

I've managed to set it a little bit in onLayout() but I can only do it to a certain value, after which, the subview will not show up. I think it is getting cropped but I cannot figure out why it get cropped and how to do it properly.

Here is the image:

The Candy Crush Icon (which is partially moved) was suppose to be moved to the right of the Coin Pirates icon (which was on the bottom and mostly hidden by the Candy Crush icon)

I managed to move the Candy Crush icon by 10 to the right, if I do it more, all of it will not show up... :(

Here is the code:

    @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);
    // Do nothing. Do not call the superclass method--that would start a layout pass
    // on this view's children. PieChart lays out its children in onSizeChanged().
//      super.onLayout(changed, l, t, r, b);
    Log.e(LOG_TAG, LOG_TAG + ".onLayout: " + this + ": "+ l + ", " + t + ", " + r + ", " + b);

//      // this is successful
//      RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) this.getLayoutParams();//new RelativeLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT );
//      lp.setMargins( lp.leftMargin + 5, lp.topMargin + 5, lp.rightMargin + 5, lp.bottomMargin + 5);
//      setLayoutParams( lp );
//      this.requestLayout();

    int iChildCount = this.getChildCount();
    for ( int i = 0; i < iChildCount; i++ ) {
        int iLeft = i * getIconSize(); // cannot be more than 10, otherwise nothing will show
        View pChild = this.getChildAt(i);
//          Log.d(LOG_TAG, LOG_TAG + ".onLayout child: " + pChild + " size: " + l + ", " + t + ", " + r + ", " + b);
        Log.d(LOG_TAG, LOG_TAG + ".onLayout child: " + pChild + " size: " + pChild.getMeasuredWidth() + ", " + pChild.getMeasuredHeight() + " :: " + pChild.getWidth() + ", " + pChild.getHeight());
        Log.d(LOG_TAG, LOG_TAG + ".onLayout child: " + pChild + " boundary: " + pChild.getLeft() + ", " + pChild.getTop() + ", " + pChild.getRight() + ", " + pChild.getBottom());

        pChild.layout(iLeft, 0, iLeft + pChild.getMeasuredWidth(), pChild.getMeasuredHeight());
//          pChild.layout(l, t, pChild.getMeasuredWidth(), pChild.getMeasuredHeight());

//          LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) pChild.getLayoutParams();
//          lp.setMargins(iLeft, 0, 0, 0);
//          pChild.setLayoutParams(lp);
//          pChild.requestLayout();
    }
}

Any help, or sample, or tutorial and explanation is highly appreciated... I've been wasting weeks in trial and errors, as I cannot find any resources about it.. The onMeasure and onLayout is under documented and is not working as said, which is very frustating:

public void layout (int l, int t, int r, int b)

Assign a size and position to a view and all of its descendants

This is the second phase of the layout mechanism. (The first is measuring). In this phase, each parent calls layout on all of its children to position them. This is typically done using the child measurements that were stored in the measure pass().

Derived classes should not override this method. Derived classes with children should override onLayout. In that method, they should call layout on each of their children.

Parameters
l   Left position, relative to parent
t   Top position, relative to parent
r   Right position, relative to parent
b   Bottom position, relative to parent 

EDIT:

Clarifying the answer

As pointed out by @Ben75, the problem is caused by incorrectly setting the pChild.layout(iTop, iLeft, iRight, iBottom); values. However, the pChild.layout is not the one called by the view's onLayout but is the one called by the parent's onLayout. The parent's onLayout iterates through every children and call their layout(iTop,iLeft,iRight,iBottom); function as well, and since it is setting the children's layout to (0,0,iWidth,iHeight), the clipping occurs

Upvotes: 0

Views: 6785

Answers (1)

ben75
ben75

Reputation: 28706

I guess the problem is here:

pChild.layout(iLeft, 0, pChild.getMeasuredWidth(), pChild.getMeasuredHeight());

Third and fourth args are right and bottom distances relative to parent. So try something like this:

pChild.layout(iLeft, 0, getMeasuredWidth()-(iLeft+pChild.getMeasuredWidth()), 0);

Upvotes: 1

Related Questions