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.