You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@flex.apache.org by chris_d_k <ck...@christiankiefer.de> on 2017/02/05 01:08:53 UTC

Flex multiline LabelItemRenderer for mobile chat

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.