Skip navigation

Most of the time, fl.containers.ScrollPane is fairly easy to use. In a recent project I used it on at least four different pages to display dynamic run-time content.

However, one of those pages seemed insistent on giving me problems. The problem was that the bottom of the dynamic content was being clipped. The scrollbar appeared, but the very bottom of the content was not visible.

My typical usage of the ScrollPane consists of three steps: First create the ScrollPane instance, second create the dynamic content, and third attach the content to the ScrollPane.

Here’s an example:

protected function build():void {
	// Step 1: create the ScrollPane
	var summarySP:ScrollPane = buildScrollPane();
	summarySP.x = 40;
	summarySP.y = 330;
	this.addChild(summarySP);
	
	// Step 2: create the content
	content = buildContent();
	
	// Step 3: attach content to ScrollPane
	summarySP.source = content;
	summarySP.invalidate();
}

protected function buildScrollPane():ScrollPane {
	var sp:ScrollPane = new ScrollPane();
	sp.setSize(550, 265);
	sp.horizontalScrollPolicy = "off";
	return sp;
}

protected function buildContent():Sprite {
	var content:Sprite = new Sprite();

	// header
	var headerContent:Sprite = new Sprite();
	var headerString:String;
	var headerField:TextField;
	var initX:int = 20;
	var initY:int = 20;
	var nextY:int = initY;
	var yspace:int = 2;
	var wspace:int = 12;
	var i:int;
	var maxI:int = selectedServicesLabel.length;
	for (i = 0; i < maxI; i++) {
		headerString = selectedServicesLabel[i];
		headerField = new CustomTextField( headerString, styles );
		headerField.x = initX;
		headerField.y = nextY;
		headerField.width = 500;
		headerContent.addChild(headerField);
		nextY += headerField.height;
	}
	content.addChild(headerContent);
	
	// footer
	var footerContent:Sprite = buildFooterContent();
	content.addChild(footerContent);
	
	return content;
}

Simple, right? Well, I included my erroneous code in that example. Did you spot it? Good for you! If not I’ll give you a big clue, the content, when it induced scrolling, consistently clipped the bottom by 20 pixels.

For those of you in the cheap seats that can’t immediately spot the problem, it is all due to setting the Y value of a child of the content. Although it is a child of the content, the content’s size does not account for the X or Y offset of its children. I go back and forth on whether this makes sense or not. Regardless, it remains true, the overall size of the content does not include the stage position of its children.

In this particular case, the design called for some whitespace, or padding, on the top and left of the dynamic content. The left/X padding didn’t matter to me, as you can see I disabled Horizontal scrolling in the ScrollPane. I was happy to have the content clipped off the right-hand side. But I could not sit idly by and allow the bottom to be clipped.

The quick fix I used was to keep the X and Y values as is, but then to fill up that unused space with some content. In this case I used the drawing API and created a 20×20 pixel transparent rectangle positioned at 0,0. This appeased the ScrollPane and finally the coveted bottom 20 pixels were included in the content’s measurements, and thus were displayed by the ScrollPane. Hurray!

Here’s the fix:

protected function buildContent():Sprite {
	var content:Sprite = new Sprite();

	// header
	var headerContent:Sprite = new Sprite();
	// top padding
	headerContent.graphics.beginFill(0xffffff, 0);
	headerContent.graphics.drawRect(0, 0, 20, 20 );
	headerContent.graphics.endFill();
	...
}

- ddb
31 Mar 2010

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.