twaver flex 编程之Group局部布局

来源:互联网 发布:matlab怎么遍历矩阵 编辑:程序博客网 时间:2024/06/05 07:19

          最近工作中被一个Group局部布局的问题搞的焦头烂额,问题是这样的,由于新设备面板要虚拟融合各种AS、AP等,在面板的有些级联端口上要求可以通过双击打开级联的设备,也就是一个子拓扑,通过Group来组合显示。遇到的问题是,采用AutoLayouter来进行自动布局时,每次布局都将所有的group元素都重新布局,导致每个端口的group显示位置混乱。而期望结果是,当打开一个端口的子拓扑时,该子拓扑固定显示在该端口下方一定位置处,再打开其他端口的子拓扑时,也一样方式显示,对之前已经打开的子拓扑的显示没有影响。

   开始的处理思路是每次打开新的子拓扑时,进行布局的对象是全局的,没有设置指定的布局对象,才导致这种现象,但是按照这种思路修改了很久也没搞定,不知道是不是还有没想到的地方。

          上述方法没搞定,于是换了一种思路,就是每次在进行新的布局之前,先将之前已经布局过的group的位置都记住,新的对象布局结束以后,再将原来的位置恢复,通过这种算是把问题解决了。

   下面是一个小小的demo,没有设置具体的样式等,只是为了说明上述两种思路,doLayout()方法是采用第二种方法解决了问题,doLayoutBySelectionModel()是第一种方法,没有解决问题。

 

<?xml version="1.0" encoding="utf-8"?><mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"xmlns:twaver="http://www.servasoftware.com/2009/twaver/flex" layout="absolute" minWidth="955" minHeight="600"creationComplete="init();"><mx:Script><![CDATA[import mx.controls.Alert;import twaver.*;import twaver.ElementBox;import twaver.Link;import twaver.Node;import twaver.network.layout.*;import twaver.network.layout.AutoLayouter;//private var box:ElementBox = network.elementBox;//private var autoLayerout:AutoLayouter = null;//private var private function init():void{    var group1:Group = creatGroup(3, "group1");    var group1_X:int = 500;            var group1_Y:int = 200;    doLayout(group1_X, group1_Y, group1.id);    //doLayoutBySelectionModel(group1_X, group1_Y, group1.id);}private function addGroup():void{    var group2:Group = creatGroup(5, "group2");    var group2_X:int = 100;    var group2_Y:int = 200;    doLayout(group2_X, group2_Y, group2.id);    //doLayoutBySelectionModel(group2_X, group2_Y, group2.id);}private function creatGroup(num:int, groupid:String):Group{    var box:ElementBox = network.elementBox;            var group:Group = new Group(groupid);    group.expanded = true;    //group.setPropertyValue("layout", layout);    var parentNode:Node = new Node();    parentNode.name = "parent";    group.addChild(parentNode);    box.add(parentNode);    for(var i:int=0; i < num; i++)    {        var node:Node = new Node();var link:Link = new Link(parentNode, node);node.name = "C" + i;group.addChild(node);group.addChild(link);box.add(node);box.add(link);    }    box.add(group);    return group;}//通过记录局部布局前各元素的位置,局部布局以后,恢复之前各元素的位置,来保证每次只布局指定的对象private function doLayout(x:int, y:int, id:Object):void{            var groupLocations:Dictionary = new Dictionary();    //遍历容器对象,保存各对象的初始位置,除了指定布局的对象    network.elementBox.forEach(function (element:IElement):void{    if(element is Group)            {if((element as Group).id != id){    groupLocations[element] = (element as Group).location;}            }});                                
var layouter2:AutoLayouter = new AutoLayouter(network);layouter2.animate=false;layouter2.explicitXOffset = x;layouter2.explicitYOffset = y;layouter2.doLayout(Consts.LAYOUT_ROUND);layouter2.animate=true;//全局布局以后,恢复之前元素的位置for(var element:* in groupLocations){var location:Point = groupLocations[element];(element as Group).location = location;}}//通过选定局部布局元素来进行局部布局private function doLayoutBySelectionModel(x:int, y:int, id:Object):void{var selectElements:ICollection = new Collection();//遍历容器中元素,根据元素id找到需要布局的元素network.elementBox.forEach(function(element:IElement):void{if(element is Group){if((element as Group).id == id){selectElements.addItem(element);}}});//选定元素network.selectionModel.setSelection(selectElements);var layouter2:AutoLayouter = new AutoLayouter(network);layouter2.animate=false;layouter2.explicitXOffset = x;layouter2.explicitYOffset = y;layouter2.doLayout(Consts.LAYOUT_ROUND);layouter2.animate=true;}]]></mx:Script><mx:VBox width="100%" height="100%" verticalGap="0" horizontalGap="0"><mx:HBox id="toolbar"><mx:HBox id="normal" horizontalGap="0"><mx:Button label="addGroup" click="addGroup()" /></mx:HBox></mx:HBox><twaver:Network id="network" width="100%" height="100%"/></mx:VBox></mx:Application>

   通过复写AutoLayouter的doLayout()方法可以定制一些复杂的布局。

      不知道第一种思路是否还有解决办法,这个后面再说吧,毕竟了解的还不多。

 

0 0
原创粉丝点击