TWaver - 專注UI技術

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

          利用Layer優(yōu)化Group顯示

          Posted on 2012-08-07 09:53 TWaver 閱讀(1063) 評論(0)  編輯  收藏
          每天逛逛TWaver論壇已經成為一種習慣,今天看到一個非常有意思的帖子:http://twaver.servasoft.com/forum/viewtopic.php?f=14&t=3129
          當兩個Group重疊時,Group中的Node會始終顯示在兩個Group之上,呈現結果如下圖(引用了帖子中的圖片):

          這簡直是無法忍受的,如果把這樣的呈現效果拿給客戶看,不被罵死才怪。我們要的是這種效果(引用了帖子中的圖片):

          帖子中給出的解決方案是:為每個Group生成一個layer,當選中Group中,將對應的layer置頂。想法很美好,現實卻很殘酷:帖子最后給出的代碼雖然可以部分實現這種效果,但是在我看來仍然不夠完美,甚至說有瑕疵。大家可以把代碼copy下來,然后運行測試:先將所有的Group展開,然后點擊group1,再點擊group2_2并拖動與group1重合,你看到了什么?
          group2_2雖然被置頂,但是它的parent:group2卻仍然被group1和group1_1遮擋了。這是因為帖子中的解決方案只是處理了當前點擊Group自身和的child Group(將child Group置頂),卻沒有處理parent Group,所以group2_2的parent:group2仍然顯示在后面。下圖是測試的結果(group1是group1_1的parent;group2是group2_2的parent;group1和group2是平級,同是group_root1的children):

          可以很明顯地看到,group2_2確實被置頂了,但是group2卻仍然被遮擋,理想的狀況下,當我們點擊group2_2的時候,group2應該緊緊跟隨在group2_2下面,并遮擋group1和group1_1,效果如下圖:

          這樣就好看多了,當我們拖動group2_2的時候,group2應該僅僅跟隨在group2_2下邊,并且遮擋住group1和group1_1。
          我把帖子中的代碼改造了一下,最終實現了這種效果,獨樂樂不如眾樂樂,下面我把我的實現代碼貼到此博客上與大家分享,如果有錯誤或可以優(yōu)化的地方希望大家可以批評指正,感激不盡!
          我們仍然沿用帖子中的設計思路:為每個Group生成一個layer,點擊Group時將layer置頂,但是我們還要考慮Group的parent Group和child Group:將child Group置頂,parent Group緊隨其后。
          首先Group可以嵌套多層,而且我們也不確定可能會嵌套幾層,所以遞歸是不可避免的了。對于這種比較復雜的算法,直觀的代碼遠遠要比語言描述有力的多,直接貼上代碼:

           1 private function init():void {
           2                 this.initBox();
           3                 network.elementBox = box;
           4                 network.addInteractionListener(function(e:InteractionEvent):void {
           5                     if(e.kind == InteractionEvent.CLICK_ELEMENT){
           6                         var g:Group = null;
           7                         if(e.element is Group){
           8                             g = Group(e.element);
           9                         }else if(e.element.parent is Group){
          10                             g = Group(e.element.parent);
          11                         }
          12 
          13                         var ele:Element=e.element as Element;
          14                         var rootGroup:Group=g;
          15                         var parentArr:ArrayCollection=new ArrayCollection;
          16                         parentArr.addItem(g);
          17                         while(ele.parent){
          18                             if(ele.parent is Group){
          19                                 rootGroup=ele.parent as Group;
          20                                 parentArr.addItem(rootGroup);
          21                             }
          22                             ele=ele.parent as Element;
          23                         }
          24                         iterator(rootGroup,parentArr);
          25                     }
          26                 });
          27             }
          28 private function iterator(parentGroup:Group,parentArr:ArrayCollection):void{
          29                 var nextParentGroup:Group=null;
          30                 var layer:Layer = box.layerBox.getLayerByID(parentGroup.id) as Layer;
          31                 if(layer){
          32                     box.layerBox.moveToBottom(layer);
          33                 }
          34                 for(var i=0;i<parentGroup.children.count;i++){
          35                     var ele:Element=parentGroup.getChildAt(i) as Element;
          36                     if(ele is Group){
          37                         var g:Group=Group(ele);
          38                         if(parentArr.contains(g)){
          39                             nextParentGroup=g;
          40                             continue;
          41                         }
          42                         var layer:Layer = box.layerBox.getLayerByID(g.id) as Layer;
          43                         if(layer){
          44                             box.layerBox.moveToBottom(layer);
          45                         }
          46                         iterator(Group(ele),parentArr);
          47                     }
          48                 }
          49                 if(nextParentGroup)
          50                     iterator(nextParentGroup,parentArr);
          51             }

          盡管語言乏力,但是為了方便大家理解,我還是盡力描述一下:
          當我點擊一個Group的時候,獲取這個Group的根Group,稱之為rootGroup,將rootGroup傳入iterator方法遞歸遍歷,把所有的Group置頂一遍,但是越是靠后置頂的,就越靠前顯示。所以為了讓我們點擊的Group能夠靠前顯示,我們需要先遍歷無關Group(例子中的group1和group1_1),最后再遍歷group2和group2_2(其中group2_2要最后遍歷)。這個遍歷先后順序怎么控制呢,通過這段代碼來控制: 

          1 if(parentArr.contains(g)){
          2     nextParentGroup=g;
          3     continue;
          4 }

          parentArr集合里包含了我們點擊的Group的所有的parent Group,我們判斷如果當前遍歷到的group在parentArr集合中,就跳過循環(huán),直到for結束后再遍歷它。
          這是大致的思路,我覺得這些描述+代碼應該可以讓大家理解,不知道這樣頻繁的置頂對效率有沒有影響,希望大家能提出優(yōu)化方案。最后附上完整的代碼見原文最下方

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


          網站導航:
           
          主站蜘蛛池模板: 绥阳县| 安岳县| 城市| 佛冈县| 灌阳县| 长汀县| 乐平市| 九寨沟县| 乐都县| 甘南县| 南丰县| 张家口市| 锦屏县| 隆子县| 铜川市| 蓝田县| 江津市| 合山市| 衡阳市| 桂东县| 铜鼓县| 乡宁县| 浪卡子县| 开平市| 德清县| 元氏县| 天峻县| 县级市| 绩溪县| 延边| 南康市| 石屏县| 广平县| 日照市| 靖边县| 子洲县| 玉门市| 西藏| 清苑县| 永新县| 九江市|