TWaver - 專注UI技術

          http://twaver.servasoft.com/
          posts - 171, comments - 191, trackbacks - 0, articles - 2
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          在TWaver Flex中實現垂直文字布局

          Posted on 2012-05-04 11:30 TWaver 閱讀(2268) 評論(1)  編輯  收藏
          最近有客戶提到如何讓Network上網元的標簽垂直顯示,首先想到的就是每個字符之間插入一個回車。這個用Network#labelFunction就能達到目的:
           1 network.labelFunction = function (element:IElement):String {
           2     var name:String = element.name;
           3     if(element.getClient('vertical')) {
           4         var result:String = '';
           5         for(var i:int=0,n:int=name.length; i<n; i++) {
           6             result += name.charAt(i) + '\n';
           7         }
           8         result = result.substr(0, result.length-1);
           9         return result;
          10     } else {
          11         return name;
          12     }
          13 };

          來段代碼測試看看:
           1 <?xml version="1.0" encoding="utf-8"?>
           2 <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
           3                 xmlns:twaver="http://www.servasoftware.com/2009/twaver/flex"
           4                 layout="absolute" width="100%" height="100%"
           5                 creationComplete="init()" backgroundColor="#FFFFFF" >
           6     <mx:Script>
           7         <![CDATA[
           8             import twaver.Consts;
           9             import twaver.ElementBox;
          10             import twaver.IElement;
          11             import twaver.Node;
          12             import twaver.Styles;
          13 
          14             private var box:ElementBox = new ElementBox();
          15 
          16             private function init():void {
          17                 network.labelFunction = function (element:IElement):String {
          18                     var name:String = element.name;
          19                     if(element.getClient('vertical')) {
          20                         var result:String = '';
          21                         for(var i:int=0,n:int=name.length; i<n; i++) {
          22                             result += name.charAt(i) + '\n';
          23                         }
          24                         result = result.substr(0, result.length-1);
          25                         return result;
          26                     } else {
          27                         return name;
          28                     }
          29                 };
          30 
          31                 var node1:Node = new Node();
          32                 node1.location = new Point(100, 100);
          33                 node1.setStyle(Styles.LABEL_POSITION, Consts.POSITION_LEFT_LEFT);
          34                 node1.setClient('vertical', true);
          35                 node1.name = '豎向文字Vertical Text';
          36                 box.add(node1);
          37 
          38                 network.elementBox = box;
          39             }
          40         ]]>
          41     </mx:Script>
          42     <twaver:Network id="network" width="100%" height="100%" />
          43 </mx:Application>

          運行效果如下:


          上面的方法很容易讓文字垂直顯示,但效果不是很理想,中英文混合時,英文也被一個字母一個字母地分開了。有沒有更好的方案?答案是肯定的,借助于Flex的Flash Text Engine (FTE)和Text Layout Framework (TLF),可以很容易地讓文字從上到下顯示。
          先來看看一個小例子,設置TextLayoutFormat的blockProgression屬性為BlockProgression.RL即可:
           1 package {
           2     import flash.display.Sprite;
           3 
           4     import flashx.textLayout.container.ContainerController;
           5     import flashx.textLayout.conversion.TextConverter;
           6     import flashx.textLayout.elements.TextFlow;
           7     import flashx.textLayout.formats.BlockProgression;
           8     import flashx.textLayout.formats.TextLayoutFormat;
           9 
          10     public class StaticHelloWorld extends Sprite {
          11         public function StaticHelloWorld() {
          12             var textLayoutFormat:TextLayoutFormat = new TextLayoutFormat();
          13             textLayoutFormat.lineHeight = 30;
          14             textLayoutFormat.locale = 'zh';
          15             textLayoutFormat.blockProgression = BlockProgression.RL;
          16 
          17             var text:String = "測試豎向文字,再看看English如何?";
          18             var textFlow:TextFlow = TextConverter.importToFlow(text, TextConverter.PLAIN_TEXT_FORMAT);
          19             textFlow.hostFormat = textLayoutFormat;
          20             textFlow.flowComposer.addController(new ContainerController(this, 25, 200));
          21             textFlow.flowComposer.updateAllControllers();
          22         }
          23     }
          24 }

          運行效果如下: 
          的確這樣效果就好多了,英文不會被一個字母一個字母地打斷,然后我們自定義一個Attachment:
            1 package {
            2     import flash.display.Sprite;
            3     import flash.text.engine.FontPosture;
            4     import flash.text.engine.FontWeight;
            5 
            6     import flashx.textLayout.container.ContainerController;
            7     import flashx.textLayout.elements.ParagraphElement;
            8     import flashx.textLayout.elements.SpanElement;
            9     import flashx.textLayout.elements.TextFlow;
           10     import flashx.textLayout.formats.BlockProgression;
           11     import flashx.textLayout.formats.TextDecoration;
           12     import flashx.textLayout.formats.TextLayoutFormat;
           13 
           14     import twaver.Styles;
           15     import twaver.network.ui.BasicAttachment;
           16     import twaver.network.ui.ElementUI;
           17 
           18     public class FTELabelAttachment extends BasicAttachment {
           19 
           20         private var textLayoutFormat:TextLayoutFormat = new TextLayoutFormat();
           21 
           22         public function FTELabelAttachment(elementUI:ElementUI, showInAttachmentCanvas:Boolean=false) {
           23             super(elementUI, showInAttachmentCanvas);
           24 
           25             this.textLayoutFormat.locale = 'zh';
           26             this.textLayoutFormat.blockProgression = BlockProgression.RL;
           27         }
           28 
           29         override public function updateProperties():void {
           30             super.updateProperties();
           31 
           32             this.textLayoutFormat.fontFamily = element.getStyle(Styles.LABEL_FONT);
           33             this.textLayoutFormat.color = element.getStyle(Styles.LABEL_COLOR);
           34             this.textLayoutFormat.fontSize = element.getStyle(Styles.LABEL_SIZE);
           35             this.textLayoutFormat.fontStyle = element.getStyle(Styles.LABEL_ITALIC) ? FontPosture.ITALIC : FontPosture.NORMAL;
           36             this.textLayoutFormat.fontWeight = element.getStyle(Styles.LABEL_BOLD) ? FontWeight.BOLD : FontWeight.NORMAL;
           37             this.textLayoutFormat.textDecoration = element.getStyle(Styles.LABEL_UNDERLINE ? TextDecoration.UNDERLINE : TextDecoration.NONE);
           38 
           39             var textFlow:TextFlow = new TextFlow();
           40             textFlow.hostFormat = this.textLayoutFormat;
           41             var p:ParagraphElement = new ParagraphElement();
           42             textFlow.addChild(p);
           43             var span:SpanElement = new SpanElement();
           44             span.text = network.getLabel(element);
           45             p.addChild(span);
           46 
           47             var fteLabel:Sprite = new Sprite();
           48             this.content = fteLabel;
           49             var containerController:ContainerController = new ContainerController(fteLabel, this.textLayoutFormat.fontSize, 1000);
           50             textFlow.flowComposer.addController(containerController);
           51             textFlow.flowComposer.updateAllControllers();
           52         }
           53 
           54         override public function get position():String {
           55             return element.getStyle(Styles.LABEL_POSITION);
           56         }
           57 
           58         override public function get xOffset():Number {
           59             return element.getStyle(Styles.LABEL_XOFFSET);
           60         }
           61 
           62         override public function get yOffset():Number {
           63             return element.getStyle(Styles.LABEL_YOFFSET);
           64         }
           65 
           66         override public function get padding():Number {
           67             return element.getStyle(Styles.LABEL_PADDING);
           68         }
           69 
           70         override public function get paddingLeft():Number {
           71             return element.getStyle(Styles.LABEL_PADDING_LEFT);
           72         }
           73 
           74         override public function get paddingRight():Number {
           75             return element.getStyle(Styles.LABEL_PADDING_RIGHT);
           76         }
           77 
           78         override public function get paddingTop():Number {
           79             return element.getStyle(Styles.LABEL_PADDING_TOP);
           80         }
           81 
           82         override public function get paddingBottom():Number {
           83             return element.getStyle(Styles.LABEL_PADDING_BOTTOM);
           84         }
           85 
           86         override public function get cornerRadius():Number {
           87             return element.getStyle(Styles.LABEL_CORNER_RADIUS);
           88         }
           89 
           90         override public function get pointerLength():Number {
           91             return element.getStyle(Styles.LABEL_POINTER_LENGTH);
           92         }
           93 
           94         override public function get pointerWidth():Number {
           95             return element.getStyle(Styles.LABEL_POINTER_WIDTH);
           96         }
           97 
           98         override public function get direction():String {
           99             return element.getStyle(Styles.LABEL_DIRECTION);
          100         }
          101 
          102         override public function get fill():Boolean {
          103             return element.getStyle(Styles.LABEL_FILL);
          104         }
          105 
          106         override public function get fillColor():Number {
          107             return element.getStyle(Styles.LABEL_FILL_COLOR);
          108         }
          109 
          110         override public function get fillAlpha():Number {
          111             return element.getStyle(Styles.LABEL_FILL_ALPHA);
          112         }
          113 
          114         override public function get gradient():String {
          115             return element.getStyle(Styles.LABEL_GRADIENT);
          116         }
          117 
          118         override public function get gradientColor():Number {
          119             return element.getStyle(Styles.LABEL_GRADIENT_COLOR);
          120         }
          121 
          122         override public function get gradientAlpha():Number {
          123             return element.getStyle(Styles.LABEL_GRADIENT_ALPHA);
          124         }
          125 
          126         override public function get contentXScale():Number {
          127             return element.getStyle(Styles.LABEL_CONTENT_XSCALE);
          128         }
          129 
          130         override public function get contentYScale():Number {
          131             return element.getStyle(Styles.LABEL_CONTENT_YSCALE);
          132         }
          133 
          134         override public function get outlineWidth():Number {
          135             return element.getStyle(Styles.LABEL_OUTLINE_WIDTH);
          136         }
          137 
          138         override public function get outlineColor():Number {
          139             return element.getStyle(Styles.LABEL_OUTLINE_COLOR);
          140         }
          141 
          142         override public function get outlineAlpha():Number {
          143             return element.getStyle(Styles.LABEL_OUTLINE_ALPHA);
          144         }
          145     }
          146 }

           再自定義Node和NodeUI,使用這個Attachment代替TWaver自帶的LabelAttachment:
          自定義Node:
           1 package {
           2     import twaver.Node;
           3 
           4     public class FTELabelNode extends Node {
           5         public function FTELabelNode(id:Object=null) {
           6             super(id);
           7         }
           8 
           9         public override function get elementUIClass():Class {
          10             return FTELabelNodeUI;
          11         }
          12     }
          13 }
           
          自定義NodeUI:
           1 package {
           2     import twaver.Node;
           3     import twaver.network.Network;
           4     import twaver.network.ui.NodeUI;
           5 
           6     public class FTELabelNodeUI extends NodeUI {
           7 
           8         private var _labelAttachment:FTELabelAttachment = null;
           9 
          10         public function FTELabelNodeUI(network:Network, node:Node) {
          11             super(network, node);
          12         }
          13 
          14         override protected function checkLabelAttachment():void{
          15             var label:String = this.network.getLabel(element);
          16             if(label != null && label != ""){
          17                 if(this._labelAttachment == null){
          18                     this._labelAttachment = new FTELabelAttachment(thisfalse);
          19                     this.addAttachment(this._labelAttachment);
          20                 }
          21             }else{
          22                 if(this._labelAttachment != null){
          23                     this.removeAttachment(this._labelAttachment);
          24                     this._labelAttachment = null;
          25                 }
          26             }
          27         }
          28     }
          29 }
          30 
           
          最后,寫個例子看看效果:
           1 <?xml version="1.0" encoding="utf-8"?>
           2 <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
           3                 xmlns:twaver="http://www.servasoftware.com/2009/twaver/flex"
           4                 layout="absolute" width="100%" height="100%"
           5                 creationComplete="init()" backgroundColor="#FFFFFF" >
           6     <mx:Script>
           7         <![CDATA[
           8             import twaver.Consts;
           9             import twaver.ElementBox;
          10             import twaver.IElement;
          11             import twaver.Node;
          12             import twaver.Styles;
          13 
          14             private var box:ElementBox = new ElementBox();
          15 
          16             private function init():void {
          17                 network.labelFunction = function (element:IElement):String {
          18                     var name:String = element.name;
          19                     if(element.getClient('vertical')) {
          20                         var result:String = '';
          21                         for(var i:int=0,n:int=name.length; i<n; i++) {
          22                             result += name.charAt(i) + '\n';
          23                         }
          24                         result = result.substr(0, result.length-1);
          25                         return result;
          26                     } else {
          27                         return name;
          28                     }
          29                 };
          30 
          31                 var node1:Node = new Node();
          32                 node1.location = new Point(100, 100);
          33                 node1.setStyle(Styles.LABEL_POSITION, Consts.POSITION_LEFT_LEFT);
          34                 node1.setClient('vertical', true);
          35                 node1.name = '豎向文字Vertical Text';
          36                 box.add(node1);
          37 
          38                 var node2:Node = new FTELabelNode();
          39                 node2.location = new Point(300, 100);
          40                 node2.setStyle(Styles.LABEL_POSITION, Consts.POSITION_LEFT_LEFT);
          41                 node2.name = '豎向文字Vertical Text';
          42                 box.add(node2);
          43 
          44                 network.elementBox = box;
          45             }
          46 
          47             private function changeFontSize():void {
          48                 box.forEach(function (element:IElement):void {
          49                     element.setStyle(Styles.LABEL_SIZE, element.getStyle(Styles.LABEL_SIZE) + 2);
          50                 });
          51             }
          52         ]]>
          53     </mx:Script>
          54     <mx:VBox width="100%" height="100%">
          55         <mx:HBox width="100%" height="20">
          56             <mx:Button label="Change Font Size" click="changeFontSize()"/>
          57         </mx:HBox>
          58         <twaver:Network id="network" width="100%" height="100%" />
          59     </mx:VBox>
          60 </mx:Application>

          恩,這就是我想要的效果 :

           更多關于FTE和TLF的信息,請參考Adobe官方文檔:
          TextLayoutFormat
          TextFlow
          textlayout
          本文完整代碼見附件:FTELabelAttachment

          評論

          # re: 在TWaver Flex中實現垂直文字布局  回復  更多評論   

          2012-05-09 12:31 by 活性炭
          挺不錯的好好

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 安丘市| 长治县| 师宗县| 十堰市| 会泽县| 平武县| 广德县| 文化| 罗定市| 怀仁县| 公安县| 常宁市| 大同县| 浏阳市| 海晏县| 怀来县| 交城县| 隆安县| 安溪县| 齐齐哈尔市| 苗栗县| 乐亭县| 台北市| 元谋县| 井陉县| 布尔津县| 海晏县| 分宜县| 屯留县| 迁西县| 胶州市| 耿马| 嘉鱼县| 澎湖县| 江陵县| 万源市| 梅河口市| 渭源县| 孝义市| 吉林市| 福建省|