Flex: dynamically sized clipping container

Here’s something that took me two days to figure out: I wanted to have a VBox nested inside another VBox, which I shall call ChildOne and Parent, respectively. I wanted to add child components to ChildOne so that ChildOne would conjure up scroll bars on demand, which is what it does by default due to the clipContent property being true by default.

That was easy enough, apart from the fact that I also wanted ChildOne to fill up Parent except for a tiny bit at the bottom, say, 20 pixels tall, which would contain a button I shall imaginatively dub ChildTwo.

All the approaches I tried at first resulted in either ChildTwo getting squashed, ChildOne extending beyond what it was supposed to, Parent conjuring up the scrollbars or some combination thereof, until I figured out that I had to code around the issue.

The solution itself was simple: compute a fixed height for ChildOne from Parent.height - ChildTwo.height. But as it turns out, the heights weren’t available during the construction of Parent, nor in the FlexEvent.CREATION_COMPLETE event handler. Fortunately, perusing the Flex documentation, I noticed ResizeEvent.RESIZE which is rather conveniently also fired upon the first layout.

The full solution, then, was approximately the following:

public class Parent extends VBox {
  private var ChildOne:VBox = new VBox();
  private var ChildTwo:Button = new Button();
  public Parent() {
    this.addEventListener(ResizeEvent.RESIZE, this.resized);
  }
  private function resized():void {
    ChildOne.height = this.height - ChildTwo.height;
  }
}

This example is reduced to the bare minimum, so it doesn’t take to account things like paddings and margins and whatnot, but it may help someone. (Hi future me! Forgot this already?)

Note: I was originally under the impression that I should be able to do this with constraint-based layouts, but when I tried it, ChildOne no longer clipped its contents, opting to expand instead which then led to Parent clipping. This seems a bit strange to me, so mayhaps I was doing something wrong. If that happens to be the case, please let me know. 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *