Flex textheight workaround

Tagged:  

I spent over an hour banging my head against the wall on this one, so I'm going to post my solution.

If you have a Flex Text component, text.textHeight gives you an incorrect result in certain situations. This is a known bug, I see it listed
http://bugs.adobe.com/jira/browse/SDK-14792 (VOTE FOR IT!) and
http://www.mail-archive.com/flexcoders@yahoogroups.com/msg63011.html.

To paraphrase the problem, basically if you create a Text component, give it a width, and a bunch of text that will cause wrapping, getting textHeight will return something about 40-50 pixels too tall.

The workaround is such:

var text:Text = new Text();
text.text = ... some text that wraps given the width.
text.explicitWidth = ... the desired width of your text component.
text.validateNow();
/* At this point, textHeight is still incorrect, 
but now at least text.measuredHeight will give us a correct result. */
text.setActualSize(itemLabel.width, text.measuredHeight + 3);
text.validateSize();

The text.measuredHeight after the validateNow will be the correct Text height. This isn't exactly the same as the textHeight, to find that out precisely you would subtract UITextField.mx_internal::TEXT_HEIGHT_PADDING (which is the constant 4).

The reason why I say text.measuredHeight + 3, is because if I don't, if you select the text and drag down, you can make the textfield scroll even though it shouldn't.

Hope this helps someone.

Thanks allot for this. You have saved me a pile of work.

Brent

Thanks a million. I've spent hours trying to figure this out - when I should have just gone to Google and found this!

After hours of googling, developing custom components and getting nowhere - this solution finally works. It works standalone as well as inside of a DG.

Thanks a bunch!

In your code sample I am missing "addChild" call to add dynamically created instance of Text class to the Display List

If you do not add Text instance to Display list, the call "text.validateNow" yields RTE, because underlying "textField" object in Text instance is not created yet.

If we look into the source file of Text.as we will see, that text.measuredHeight is calculated dependant on text.textHeight property in line 415.

Thus, I conclude that if text.measuredHeight returns correct value, then text.textHeight is doing the same because they are mutually connected.

I'm working on a project that is displaying html in the Flex Text component (via htmlText). I don't have the height set on the text component so that it will size itself to the content. It works great for showing basic html (b, i, u) but when it encounters an image tag, (img) it does resize to fit. Do you have answers to some or any of the questions I have below?

1. Is there a way to know when the image(s) have been completely loaded in the text component?

2. While debugging I spotted a property called textHeight and it has a greater height than the text component's height. BTW I set a timeout to check well after the images have loaded. When I set the component height to the textHeight value it shows more of the comment but it is still too short and cuts off the image(s).

3. While still in the same debugging session I spotted another property in the debugger called, "$height". It was at the very top of the properties list and the icon was a mysterious yellow. When I set the component to this value I got the correct height! How do I get at this property?

4. Let's say I find a way to set the component to the correct height. Is there a way to undefine the height so that it goes back to autosizing itself (albeit incorrectly but even so)? For example, mytext.height = null; // component remeasures itself after this statement

Had this issue and went in a slightly different direction on how to fix it today:
http://thoughts.novaleaf.com/johanm/2008/12/03/flex-solution-to-automati...
Would like your feedback as to how viable it is for others. (See previous post for more info and the link-back to your blog.)

//Johan Munkestam