Hi there,

searching for a solution to create a multiline LabelItemRenderer for a
mobile chat
I found
http://flexponential.com/2011/08/21/adding-multiline-text-support-to-labelitemrenderer/

My code is below. The problem is that after scolling the Height of the
ItemRenderers do not fit anymore - it seems that they get the wrong heights
of reused renderers. What am I doing wrong?

public class ChatMessageItemRenderer extends MultilineLabelItemRenderer
        {

                private static const CORNER_RADIUS:int = 10;
                private static const SIDE_OFFSET:int = 40;

                public function ChatMessageItemRenderer()
                {
                        super();
                        minHeight = 0;
                        percentWidth = 100;
                }

                private var dataChanged:Boolean;
                override public function set data(value:Object):void
                {
                        super.data = value;
                        dataChanged = true;
                        invalidateProperties();
                        invalidateDisplayList();
                }

                override protected function commitProperties():void
                {
                    super.commitProperties();
                        if(dataChanged)
                        {
                                labelDisplay.text = data.message;
                                dataChanged = false;
                        }
                }

                override protected function 
updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void
                {
                    super.updateDisplayList(unscaledWidth, unscaledHeight);
                        setElementPosition(labelDisplay, data.isOwn ? 0 : 
SIDE_OFFSET,
labelDisplay.getLayoutBoundsY());

                }

                // -------------------------------------------------

                override protected function drawBackground(unscaledWidth:Number,
unscaledHeight:Number):void
                {
                        var backgroundColor:int = data.isOwn ? 0xFF0000 : 
0x00FF00;

                        graphics.beginFill(backgroundColor);
                        graphics.drawRoundRect(data.isOwn ? 0 : SIDE_OFFSET, 0, 
unscaledWidth -
SIDE_OFFSET, unscaledHeight, CORNER_RADIUS, CORNER_RADIUS);
                        graphics.endFill();
                }


        
////////////////////////////////////////////////////////////////////////////
                //
        
////////////////////////////////////////////////////////////////////////////

                private var oldUnscaledWidth:Number;

                /**
                 * Upgrade layoutContents to handle text reflow.
                 */
                override protected function layoutContents(unscaledWidth:Number,
unscaledHeight:Number):void
                {
                        if(!labelDisplay)
                        {
                                return;
                        }

                        var paddingLeft:Number = getStyle("paddingLeft");
                        var paddingRight:Number = getStyle("paddingRight");
                        var paddingTop:Number = getStyle("paddingTop");
                        var paddingBottom:Number = getStyle("paddingBottom");
                        var verticalAlign:String = getStyle("verticalAlign");

                        var viewWidth:Number = unscaledWidth - paddingLeft - 
paddingRight;
                        var viewHeight:Number = unscaledHeight - paddingTop - 
paddingBottom;

                        var vAlign:Number;
                        if(verticalAlign == "top")
                        {
                                vAlign = 0;
                        }
                        else if(verticalAlign == "bottom")
                        {
                                vAlign = 1;
                        }
                        else // if (verticalAlign == "middle")
                        {
                                vAlign = 0.5;
                        }

                        if(label != "")
                        {
                                labelDisplay.commitStyles();
                        }

                        // Size the labelDisplay

                        // we want the labelWidth to be the viewWidth and then 
we'll calculate
the height
                        // of the text from that
                        var labelWidth:Number = Math.max(viewWidth - 
SIDE_OFFSET, 0);

                        // keep track of the old label height
                        var oldPreferredLabelHeight:Number = 0;

                        // We get called with unscaledWidth = 0 a few times...
                        // rather than deal with this case normally,
                        // we can just special-case it later to do something 
smarter
                        if(labelWidth == 0)
                        {
                                // if unscaledWidth is 0, we want to make sure 
labelDisplay is
invisible.
                                // we could set labelDisplay's width to 0, but 
that would cause an extra
                                // layout pass because of the text reflow 
logic.  To avoid that we can
                                // just set its height to 0 instead of setting 
the width.
                                setElementSize(labelDisplay, NaN, 0);
                        }
                        else
                        {
                                // grab old height before we resize the 
labelDisplay
                                oldPreferredLabelHeight = 
getElementPreferredHeight(labelDisplay);

                                // keep track of oldUnscaledWidth so we have a 
good guess as to the
width
                                // of the labelDisplay on the next measure() 
pass
                                oldUnscaledWidth = unscaledWidth;

                                // set the width of labelDisplay to labelWidth.
                                // set the height to old label height.  If the 
height's actually wrong,
                                // we'll invalidateSize() and go through this 
layout pass again anyways
                                setElementSize(labelDisplay, labelWidth, 
oldPreferredLabelHeight);

                                // grab new labelDisplay height after the 
labelDisplay has taken its
final width
                                var newPreferredLabelHeight:Number =
getElementPreferredHeight(labelDisplay);

                                // if the resize caused the labelDisplay's 
height to change (because of
                                // text reflow), then we need to re-measure 
ourselves with our new width
                                if(oldPreferredLabelHeight != 
newPreferredLabelHeight)
                                {
                                        invalidateSize();
                                }
                        }

                        // Position the labelDisplay

                        var labelY:Number = Math.round(vAlign * (viewHeight -
oldPreferredLabelHeight)) + paddingTop;
                        setElementPosition(labelDisplay, paddingLeft, labelY);
                }

        
////////////////////////////////////////////////////////////////////////////
                // HELPER METHODS
        
////////////////////////////////////////////////////////////////////////////

                override protected function createLabelDisplay():void
                {
                        super.createLabelDisplay();
                        labelDisplay.multiline = true;
                        labelDisplay.wordWrap = true;
                        labelDisplay.styleDeclaration =
styleManager.getStyleDeclaration(".myStyle");
                        labelDisplay.setStyle("paddingTop", 10);
                        labelDisplay.setStyle("paddingLeft", 10);
                        labelDisplay.setStyle("paddingRight", 10);
                        labelDisplay.setStyle("paddingBottom", 10);
                }

        }

// 

<?xml version="1.0"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009";
xmlns:s="library://ns.adobe.com/flex/spark"
creationComplete="addDummyList()">

    <fx:Script>
        
    </fx:Script>


    <s:List id="messageList"
            itemRenderer="MyItemRenderer"
            horizontalScrollPolicy="off"
            useVirtualLayout="true">
        <s:layout>
            <s:VerticalLayout id="vlayout">
            </s:VerticalLayout>
        </s:layout>
    </s:List>

</s:Group>




--
View this message in context: 
http://apache-flex-users.2333346.n4.nabble.com/Flex-multiline-LabelItemRenderer-for-mobile-chat-tp14612.html
Sent from the Apache Flex Users mailing list archive at Nabble.com.

Reply via email to