利用Layer优化Group显示

news/2024/7/10 2:43:19 标签: layer, 优化, iterator, function, 语言, 测试

每天逛逛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):

优化前的显示" width="488" height="436" class="alignnone size-full wp-image-4782" />

可以很明显地看到,group2_2确实被置顶了,但是group2却仍然被遮挡,理想的状况下,当我们点击group2_2的时候,group2应该紧紧跟随在group2_2下面,并遮挡group1和group1_1,效果如下图:

优化以后最终效果" width="555" height="407" class="alignnone size-full wp-image-4783" />

这样就好看多了,当我们拖动group2_2的时候,group2应该仅仅跟随在group2_2下边,并且遮挡住group1和group1_1。

我把帖子中的代码改造了一下,最终实现了这种效果,独乐乐不如众乐乐,下面我把我的实现代码贴到此博客上与大家分享,如果有错误或可以优化的地方希望大家可以批评指正,感激不尽! 

我们仍然沿用帖子中的设计思路:为每个Group生成一个layer,点击Group时将layer置顶,但是我们还要考虑Group的parent Group和child Group:将child Group置顶,parent Group紧随其后。首先Group可以嵌套多层,而且我们也不确定可能会嵌套几层,所以递归是不可避免的了。对于这种比较复杂的算法,直观的代码远远要比语言描述有力的多,直接贴上代码:

private function init():void {
				this.initBox();
				network.elementBox = box;
				network.addInteractionListener(function(e:InteractionEvent):void {
					if(e.kind == InteractionEvent.CLICK_ELEMENT){
						var g:Group = null;
						if(e.element is Group){
							g = Group(e.element);
						}else if(e.element.parent is Group){
							g = Group(e.element.parent);
						}

						var ele:Element=e.element as Element;
						var rootGroup:Group=g;
						var parentArr:ArrayCollection=new ArrayCollection;
						parentArr.addItem(g);
						while(ele.parent){
							if(ele.parent is Group){
								rootGroup=ele.parent as Group;
								parentArr.addItem(rootGroup);
							}
							ele=ele.parent as Element;
						}
						iterator(rootGroup,parentArr);
					}
				});
			}
private function iterator(parentGroup:Group,parentArr:ArrayCollection):void{
				var nextParentGroup:Group=null;
				var layer:Layer = box.layerBox.getLayerByID(parentGroup.id) as Layer;
				if(layer){
					box.layerBox.moveToBottom(layer);
				}
				for(var i=0;i<parentGroup.children.count;i++){
					var ele:Element=parentGroup.getChildAt(i) as Element;
					if(ele is Group){
						var g:Group=Group(ele);
						if(parentArr.contains(g)){
							nextParentGroup=g;
							continue;
						}
						var layer:Layer = box.layerBox.getLayerByID(g.id) as Layer;
						if(layer){
							box.layerBox.moveToBottom(layer);
						}
						iterator(Group(ele),parentArr);
					}
				}
				if(nextParentGroup)
					iterator(nextParentGroup,parentArr);
			}

尽管语言乏力,但是为了方便大家理解,我还是尽力描述一下:

当我点击一个Group的时候,获取这个Group的根Group,称之为rootGroup,将rootGroup传入iterator方法递归遍历,把所有的Group置顶一遍,但是越是靠后置顶的,就越靠前显示。所以为了让我们点击的Group能够靠前显示,我们需要先遍历无关Group(例子中的group1和group1_1),最后再遍历group2和group2_2(其中group2_2要最后遍历)。这个遍历先后顺序怎么控制呢,通过这段代码来控制:

if(parentArr.contains(g)){
	nextParentGroup=g;
	continue;
}

parentArr集合里包含了我们点击的Group的所有的parent Group,我们判断如果当前遍历到的group在parentArr集合中,就跳过循环,直到for结束后再遍历它。这是大致的思路,我觉得这些描述+代码应该可以让大家理解,不知道这样频繁的置顶对效率有没有影响,希望大家能提出优化方案。最后附上完整的代码demo(见原文最下方)


http://www.niftyadmin.cn/n/1765835.html

相关文章

MATLAB-ginput函数问题

functions&#xff1a;Graphical input from mouse or cursor ginput提供了一个十字光标使我们能更精确的选择我们所需要的位置&#xff0c;并返回坐标值。函数调用形式为&#xff1a; [x,y] ginput(n) [x,y] ginput [x,y,button] ginput(...) 对于[x,y] ginput(n)&#x…

Unicode 环境下的字符串的操作

1.CString转int int i _ttoi( str ); 2.保存中文和读取中文&#xff1a; CSdtioFile在Unicode环境下默认是不支持中文的&#xff0c;若需要存储和读取中文需要设置代码页&#xff1a; #include "locale.h" ::_wsetlocale( LC_ALL, _T("chs") ); // 设置当前…

自定义Background

TWaver提供了ImageBackground来为TNetwork设置背景&#xff0c;ImageBackground可以设置为颜色&#xff0c;渐变色&#xff0c;图片或纹理&#xff0c;但是如果想设置多张图片为背景&#xff0c;或者需要准确的定位背景&#xff08;比如居中&#xff09;&#xff0c;ImageBackg…

html添加mp3背景音乐全兼容办法

做小项目的时候遇到的&#xff0c;ie支持embed标签&#xff0c;firefox和谷歌都不支持&#xff0c;而且ie里面载入的音乐是循环播放的&#xff0c;谷歌和火狐浏览器只能播放一次&#xff0c;找了插件&#xff0c;试了object加载swf的方法&#xff0c;都不能解决&#xff0c;最后…

如何让HTML5的表格支持后台排序与分页

TWaver HTML5发布已有一段时间&#xff0c;使用的客户也是逐渐增加&#xff0c;于是我也迫不及待地申请了一个试用版来写一个小网页&#xff0c;最近正在写到数据查询&#xff0c;表格显示的功能。表格组件在HTML5中是提供的&#xff0c;查看TWaver提供的Demo,表格的使用还是比…

MySql中创建用户,授权

第一天搞MySql好多东西都不会&#xff0c;幸好有网络的强大资源,首先需要注意的是任何一条sql语句都是要以分号结尾的&#xff0c;不然很是蛋疼的 1.新建用户。//登录MYSQL>mysql -u root -p>密码//创建用户mysql> insert into mysql.user(Host,User,Password,ssl_cip…

如何在TWaver Flex中定制Tree的tooltip

如果您显示过Tree的ToolTip&#xff0c;会发现这个tooltip离鼠标太远了&#xff1b;而且也无法跟随鼠标一起移动&#xff1b;最重要的是&#xff0c;如果想动态更改tooltip也很麻烦。 还是自定义ToolTip灵活&#xff1a; 1. 设置tree.toolTipFunction&#xff0c;关闭默认的to…

TWaver With JavaFX

JavaFX Script被抛弃以后&#xff0c;很久不关心JavaFX了&#xff0c;偶然发现JavaFX已经发展到2.2&#xff0c;而且已经绑定到JDK7中&#xff0c;看来Oracle对它还是蛮重视的。 看到有人在论坛提问TWaver有没有JavaFX版本&#xff0c;于是去Oracle网站上逛了一下&#xff0c;…