最近有客户提到如何让Network上网元的标签垂直显示,首先想到的就是每个字符之间插入一个回车。这个用Network#labelFunction就能达到目的:
network.labelFunction = function (element:IElement):String { var name:String = element.name; if(element.getClient('vertical')) { var result:String = ''; for(var i:int=0,n:int=name.length; i<n; i++) { result += name.charAt(i) + '\n'; } result = result.substr(0, result.length-1); return result; } else { return name; } };
来段代码测试看看:
运行效果如下:
上面的方法很容易让文字垂直显示,但效果不是很理想,中英文混合时,英文也被一个字母一个字母地分开了。有没有更好的方案?答案是肯定的,借助于Flex的Flash Text Engine (FTE)和Text Layout Framework (TLF),可以很容易的让文字从上到下显示。
先来看看一个小例子,设置TextLayoutFormat的blockProgression属性为BlockProgression.RL即可:
运行效果如下:
的确这样效果就好多了,英文不会被一个字母一个字母地打断,然后我们自定义一个Attachment:
package { import flash.display.Sprite; import flash.text.engine.FontPosture; import flash.text.engine.FontWeight; import flashx.textLayout.container.ContainerController; import flashx.textLayout.elements.ParagraphElement; import flashx.textLayout.elements.SpanElement; import flashx.textLayout.elements.TextFlow; import flashx.textLayout.formats.BlockProgression; import flashx.textLayout.formats.TextDecoration; import flashx.textLayout.formats.TextLayoutFormat; import twaver.Styles; import twaver.network.ui.BasicAttachment; import twaver.network.ui.ElementUI; public class FTELabelAttachment extends BasicAttachment { private var textLayoutFormat:TextLayoutFormat = new TextLayoutFormat(); public function FTELabelAttachment(elementUI:ElementUI, showInAttachmentCanvas:Boolean=false) { super(elementUI, showInAttachmentCanvas); this.textLayoutFormat.locale = 'zh'; this.textLayoutFormat.blockProgression = BlockProgression.RL; } override public function updateProperties():void { super.updateProperties(); this.textLayoutFormat.fontFamily = element.getStyle(Styles.LABEL_FONT); this.textLayoutFormat.color = element.getStyle(Styles.LABEL_COLOR); this.textLayoutFormat.fontSize = element.getStyle(Styles.LABEL_SIZE); this.textLayoutFormat.fontStyle = element.getStyle(Styles.LABEL_ITALIC) ? FontPosture.ITALIC : FontPosture.NORMAL; this.textLayoutFormat.fontWeight = element.getStyle(Styles.LABEL_BOLD) ? FontWeight.BOLD : FontWeight.NORMAL; this.textLayoutFormat.textDecoration = element.getStyle(Styles.LABEL_UNDERLINE ? TextDecoration.UNDERLINE : TextDecoration.NONE); var textFlow:TextFlow = new TextFlow(); textFlow.hostFormat = this.textLayoutFormat; var p:ParagraphElement = new ParagraphElement(); textFlow.addChild(p); var span:SpanElement = new SpanElement(); span.text = network.getLabel(element); p.addChild(span); var fteLabel:Sprite = new Sprite(); this.content = fteLabel; var containerController:ContainerController = new ContainerController(fteLabel, this.textLayoutFormat.fontSize, 1000); textFlow.flowComposer.addController(containerController); textFlow.flowComposer.updateAllControllers(); } override public function get position():String { return element.getStyle(Styles.LABEL_POSITION); } override public function get xOffset():Number { return element.getStyle(Styles.LABEL_XOFFSET); } override public function get yOffset():Number { return element.getStyle(Styles.LABEL_YOFFSET); } override public function get padding():Number { return element.getStyle(Styles.LABEL_PADDING); } override public function get paddingLeft():Number { return element.getStyle(Styles.LABEL_PADDING_LEFT); } override public function get paddingRight():Number { return element.getStyle(Styles.LABEL_PADDING_RIGHT); } override public function get paddingTop():Number { return element.getStyle(Styles.LABEL_PADDING_TOP); } override public function get paddingBottom():Number { return element.getStyle(Styles.LABEL_PADDING_BOTTOM); } override public function get cornerRadius():Number { return element.getStyle(Styles.LABEL_CORNER_RADIUS); } override public function get pointerLength():Number { return element.getStyle(Styles.LABEL_POINTER_LENGTH); } override public function get pointerWidth():Number { return element.getStyle(Styles.LABEL_POINTER_WIDTH); } override public function get direction():String { return element.getStyle(Styles.LABEL_DIRECTION); } override public function get fill():Boolean { return element.getStyle(Styles.LABEL_FILL); } override public function get fillColor():Number { return element.getStyle(Styles.LABEL_FILL_COLOR); } override public function get fillAlpha():Number { return element.getStyle(Styles.LABEL_FILL_ALPHA); } override public function get gradient():String { return element.getStyle(Styles.LABEL_GRADIENT); } override public function get gradientColor():Number { return element.getStyle(Styles.LABEL_GRADIENT_COLOR); } override public function get gradientAlpha():Number { return element.getStyle(Styles.LABEL_GRADIENT_ALPHA); } override public function get contentXScale():Number { return element.getStyle(Styles.LABEL_CONTENT_XSCALE); } override public function get contentYScale():Number { return element.getStyle(Styles.LABEL_CONTENT_YSCALE); } override public function get outlineWidth():Number { return element.getStyle(Styles.LABEL_OUTLINE_WIDTH); } override public function get outlineColor():Number { return element.getStyle(Styles.LABEL_OUTLINE_COLOR); } override public function get outlineAlpha():Number { return element.getStyle(Styles.LABEL_OUTLINE_ALPHA); } } }再自定义Node和NodeUI,使用这个Attachment代替TWaver自带的LabelAttachment:
自定义Node:
自定义NodeUI:
最后,写个例子看看效果:
恩,这就是我想要的效果:
更多关于FTE和TLF的信息,请参考Adobe官方文档:
TextLayoutFormat
TextFlow
Textlayout
本文完整代码见附件:FTELabelAttachment