2

I have spent the whole day debugging various ways to add custom ViewGroup into another custom ViewGroup and nearly went crazy because none of them works, and there is no official documentation or sample that shows how it can be done...

Basically, I have 2 custom ViewGroup:

  1. HorizontalDockView extends ViewGroup
  2. GameEntryView extends FrameLayout

HorizontalDockView overrides onDraw, onMeasure, etc and everything is called normally and works perfectly. However, when I create GameEntryView from inside HorizontalDockView's constructor and call addView(gameEntryView), the gameEntryView will never ever show regardless of the layoutParams, addView called from whatever thread, or however I call, load, and setContentView on the parent HorizontalDockView. If I list through the horizontalDockView.getChildAt(); all the gameEntryView objects are still there.

Hopeless, I try to debug through GameEntryView's onDraw, onMeasure, dispatchDraw methods and realized none of them actually get called! No.. not even once!

Do I need to iterate through all the child view in the parent (HorizontalDockView's) on* call and call the children's on* explicitly? I was just calling super.on*() on the parent.

I did call setWillNotDraw( false ); on both the parent and the child class.

How do I get the child to show up inside the parent's view? simple sample or existing small open source project is highly appreciated!

Thank you very much!

Zennichimaro
  • 5,236
  • 6
  • 54
  • 78

1 Answers1

5

Did you overwrite onLayout? When Android lays out your ViewGroup, your ViewGroup is responsible for laying out the children.

This code is from a custom ViewGroup that lays out all children on top of each other:

@Override
protected void onLayout(final boolean changed, final int l, final int t, final int r, final int b) {

    int count = this.getChildCount();
    for (int i = 0; i < count; i++) {

        View child = this.getChildAt(i);
        child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight());
    }
}

For completeness, the onMeasure override:

@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {

    int parentWidth  = MeasureSpec.getSize(widthMeasureSpec);
    int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
    this.setMeasuredDimension(parentWidth, parentHeight);

    int count = this.getChildCount();
    for (int i = 0; i < count; i++) {

        View child = this.getChildAt(i);
        this.measureChild(
            child,
            MeasureSpec.makeMeasureSpec(parentWidth, MeasureSpec.EXACTLY),
            MeasureSpec.makeMeasureSpec(parentHeight, MeasureSpec.EXACTLY));
    }
}
Fabian Zeindl
  • 5,860
  • 8
  • 54
  • 78
  • Thanks! I override onLayout and onMeasure on the child view class, but I did not override onLayout on parent view class! I called super.onMeasure() on parent view class but apparently that is not working. Thanks a lot for pointing it out! – Zennichimaro Jul 11 '13 at 02:01
  • Hi @FabianZeindl, what if I want the children to layout sequentially like LinearLayout instead of overlapping each other? – Zennichimaro Jul 25 '13 at 09:42
  • Android layouting is really complicated there (because of display fragmentation and over-generalizing everything). You can just adapt your onLayout to give other positions and sizes to your children, which you calculate beforehand. It takes a good implementation of the onMeasure method that your children "behave" and display the right way as well. Just try it. – Fabian Zeindl Jul 25 '13 at 11:36