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.