TWaver - 專注UI技術

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

          替換TWaver中Tree展開合并圖標

          Posted on 2012-06-12 10:45 TWaver 閱讀(1071) 評論(0)  編輯  收藏
          TWaver最大的優點之一是“靈活的定制功能”。光說不練不行,來個例子演練一下:定制Tree節點的標簽。
          • 默認Tree和Network上的標簽顯示的是網元的name屬性,設置Styles.TREE_LABEL屬性后,可以讓Tree顯示Styles.TREE_LABEL的值,以達到Tree和Network顯示不同標簽的目的
          • 如果覺得這樣還不夠,可以設置Tree#labelFunction,比如下面的代碼可以讓Node顯示name,Link顯示Styles.TREE_LABEL:
          1 tree.labelFunction = function(e:IElement):String{
          2     if(e is Link){
          3         return e.getStyle(Styles.TREE_LABEL);
          4     }else{
          5         return e.name;
          6     }
          7 }

          既然TWaver這么靈活,那Tree的展開合并圖標能定制么?
          先來看看用最原始的方式:
          1. 先定義2個class:
          2. 1 [Embed(source="assets/plus.png")]
            2 [Bindable]
            3 public var plus:Class;
            4 
            5 [Embed(source="assets/minus.png")]
            6 [Bindable]
            7 public var minus:Class;


          3. 再設置Tree的disclosureOpenIcon和disclosureClosedIcon屬性為上面定義的class
          4. 1 <tw:Tree id="tree2" width="100%" height="100%" disclosureOpenIcon="{minus}" 
            disclosureClosedIcon="{plus}"/>

             效果如下:
               有同學就要問了,這樣還是不夠靈活,資源文件直接嵌入了SWF中,如果想換個圖標,還得重新編譯打包上傳一把。這好說,可以用css定制組件樣式(其實css也要編譯成swf,這點adobe完全沒有考慮到用戶的實際需求,換個顏色還得編譯swf,以后有時間給大家說說如何不編譯swf也能用css定制樣式),但是偏偏disclosureOpenIcon和disclosureClosedIcon無法用css定制樣式。從mx.controls.Tree的源代碼中可以看到
          1 [Style(name="disclosureOpenIcon", type="Class", format="EmbeddedFile", inherit="no")]
          2 [Style(name="disclosureClosedIcon", type="Class", format="EmbeddedFile", inherit="no")]
          3 

               這說明,disclosureOpenIcon和disclosureClosedIcon的style類型為class,css可以加載class?肯定不行,不信邪的同學可以試試:
          1 <mx:Style>
          2     Tree {
          3         disclosureOpenIcon: "assets/minus.png";
          4         disclosureClosedIcon: "assets/plus.png";
          5     }
          6 </mx:Style>

          運行程序會得到下面的錯誤:

          TypeError: Error #1034: Type Coercion failed: cannot convert “assets/plus.png” to Class.
          at mx.controls::Tree/initListData()[C:\autobuild\3.5.0\frameworks\projects\framework\src\mx\controls\Tree.as:2663]

          那我們就定義兩個class,但是這兩個class是什么class?我們來分析一下:
          1. 既然是圖片,我們就繼承Image組件吧。
          2. 既然是class,說明mx內部會不停地new這個class,所以圖片資源要緩存起來。
          3. 加載圖片是異步的,所以要等圖片加載完成后,再注冊這個class。
          因此就有了這2個類的定義:
           1 package {
           2     import flash.display.Bitmap;
           3     import flash.display.Loader;
           4 
           5     import mx.controls.Image;
           6 
           7     public class disclosureOpenIcon extends Image {
           8         public static const loader:Loader = new Loader();
           9 
          10         public function disclosureOpenIcon() {
          11             this.source = new Bitmap(Bitmap(loader.content).bitmapData);
          12             this.width = loader.content.width;
          13             this.height = loader.content.height;
          14         }
          15     }
          16 }
          17 
          18 package {
          19     import flash.display.Bitmap;
          20     import flash.display.Loader;
          21 
          22     import mx.controls.Image;
          23 
          24     public class disclosureClosedIcon extends Image {
          25         public static const loader:Loader = new Loader();
          26 
          27         public function disclosureClosedIcon() {
          28             this.source = new Bitmap(Bitmap(loader.content).bitmapData);
          29             this.width = loader.content.width;
          30             this.height = loader.content.height;
          31         }
          32     }
          33 }

          下面是定制Tree展開合并圖標的代碼:
           1 private static function registTreeDisclosureIcon(tree:UIComponent):void {
           2     registClassStyle(tree, disclosureOpenIcon, "assets/minus.png");
           3     registClassStyle(tree, disclosureClosedIcon, "assets/plus.png");
           4 }
           5 
           6 private static function registClassStyle(component:UIComponent, clazz:Class, value:String):void {
           7     if(clazz["loader"].content == null){
           8         clazz["loader"].contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void {
           9             component.setStyle(getQualifiedClassName(clazz), clazz);
          10         });
          11         clazz["loader"].load(new URLRequest(value), new LoaderContext(true));
          12     }
          13 }

          如果想全局注冊,可以考慮下面的代碼:
           1 private static function registTreeDisclosureIcon():void {
           2     var css:CSSStyleDeclaration = StyleManager.getStyleDeclaration("Tree");
           3     registClassStyle(css, disclosureOpenIcon, "assets/minus.png");
           4     registClassStyle(css, disclosureClosedIcon, "assets/plus.png");
           5 }
           6 
           7 private static function registClassStyle(css:CSSStyleDeclaration, clazz:Class, value:String):void {
           8     if(clazz["loader"].content == null){
           9         clazz["loader"].contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void {
          10             css.setStyle(getQualifiedClassName(clazz), clazz);
          11         });
          12         clazz["loader"].load(new URLRequest(value), new LoaderContext(true));
          13     }
          14 }

           最后看看擺脫mx.controls.Tree的FastTree怎么定制展開合并圖標,比如下面的代碼就讓展開合并圖標顛倒了:
          1 tree4.expandIcon = "collapsed_icon";
          2 tree4.collapseIcon = "expanded_icon";

          本文完整代碼見附件:TreeDisclosureIcon

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


          網站導航:
           
          主站蜘蛛池模板: 甘谷县| 顺义区| 龙南县| 紫云| 禄劝| 获嘉县| 祁阳县| 喀喇| 宜黄县| 酉阳| 杭锦后旗| 革吉县| 尖扎县| 白朗县| 都兰县| 武威市| 高邑县| 出国| 阿勒泰市| 凤山市| 新营市| 广宁县| 安乡县| 上虞市| 沁水县| 民乐县| 仁布县| 丰顺县| 仁化县| 红桥区| 陆良县| 江阴市| 油尖旺区| 石台县| 崇礼县| 丰城市| 棋牌| 新河县| 衡阳市| 九龙城区| 土默特左旗|