2
votes

For a multi-line TextArea Flex component, want to be able to keep entering text and have the TextArea auto-resize in the vertical direction so that all the entered text is shown at once. However, TextArea wants to push any components down in the layout flow. Instead, want the TextArea to extend over on top of them. Once the text entry is done, then the TextArea should shrink back and redraw itself to its normal bounds.

2

2 Answers

0
votes

If the container the TextArea is in is using 'absolute' positioning (like a Canvas), this will work. Just measure textHeight on the TextArea and when it gets to a certain range within the TextArea's height, make the height bigger. You'll still have to fix the z-order, though, because the TextArea may want to stretch down behind other components.

0
votes

Sub-class the TextArea class and override the measure() method to set the measured dimensions to the size of the text of the text area. You can also add in event listeners to invalidate the size and parent size of the sub classed TextArea on text input or a re-layout of the parent.

This is a simple class that I've created:

public class AutoAdjustTextArea extends TextArea{

/////////////////////////////////////////////////
//Constructor Method/////////////////////////////
/////////////////////////////////////////////////
    public function AutoAdjustTextArea():void{
        super.addEventListener(FlexEvent.ADD, this.invalidateSizeOnEvent, false, 0, true);
        super.addEventListener(Event.CHANGE, this.invalidateSizeOnEvent, false, 0, true);
        super.addEventListener(TextEvent.TEXT_INPUT, this.invalidateSizeOnEvent, false, 0, true);
        super.addEventListener(ResizeEvent.RESIZE, this.invalidateSizeOnEvent, false, 0, true);
    }


/////////////////////////////////////////////////
//Set Methods////////////////////////////////////
/////////////////////////////////////////////////
    override public function set text(value:String):void{
        super.text = value;
        this.invalidateSizeOnEvent();
    }


/////////////////////////////////////////////////
//Measure Methods////////////////////////////////
/////////////////////////////////////////////////
    override protected function measure():void{

    //Calls the super method
        super.measure();

    //Calls to ensure this is validated
        super.validateNow();
        super.textField.validateNow();

    //Grabs the min and max height values
        var minHeight:Number = super.minHeight;
        var maxHeight:Number = super.maxHeight;

    //Grabs the height of the text
        var textHeight:Number = super.textField.textHeight + 4;//+4 for the two pixel gutter on the top and bottom

    //Calculates the preferredHeight
        var preferredHeight:Number = textHeight;
        if(isNaN(minHeight) == false && preferredHeight < minHeight)
            preferredHeight = minHeight;
        else if(isNaN(maxHeight) == false && preferredHeight > maxHeight)
            preferredHeight = maxHeight;

    //Sets the measured dimensions
        super.measuredHeight = preferredHeight;
    }


/////////////////////////////////////////////////
//Event Listener Methods/////////////////////////
/////////////////////////////////////////////////
    private function invalidateSizeOnEvent(event:Event = null):void{
        super.invalidateProperties();
        super.invalidateSize();
        super.invalidateParentSizeAndDisplayList();
    }