如何开发像Elixir这样的 UI ,我们可以在其中选择多个对象并拖动。我们可以通过 ctrl+click 或从 selectionBox 中选择项目。
我正在使用画布并添加一些自定义组件。我想通过选择多个并拖动,选择多个并删除等来重新排列。
任何想法?
如何开发像Elixir这样的 UI ,我们可以在其中选择多个对象并拖动。我们可以通过 ctrl+click 或从 selectionBox 中选择项目。
我正在使用画布并添加一些自定义组件。我想通过选择多个并拖动,选择多个并删除等来重新排列。
任何想法?
在这里,我可以给你一个简单的起点。
但是,在那之前,我并没有花太多时间在这个组件上。请仅作为示例参考。你可能想写你自己的。
下面的组件使用一个额外的Canvas
调用selectionLayer
来进行多次拖动。当您选择一个项目时,项目将从主目录中删除Canvas
并添加到selectionLayer
. 如果您拖动,它会调用selectionLayer.startDrag()
,以便图层中的所有内容将一起移动。当拖动完成时,它会检查图层更改的 x,y 位置(因为子组件实际上没有移动;selectionLayer
确实如此)并将其应用于拖动的组件,同时移动selectionLayer
到原始位置(0,0)
。
DraggableCanvas.as:
package
{
import flash.display.DisplayObject;
import flash.events.Event;
import flash.events.MouseEvent;
import mx.containers.Canvas;
import mx.core.UIComponent;
public class DraggableCanvas extends Canvas
{
protected var selectionLayer:Canvas;
protected var isDragging:Boolean;
public function DraggableCanvas()
{
super();
isDragging = false;
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
protected function addedToStageHandler(event:Event):void
{
stage.addEventListener(MouseEvent.MOUSE_DOWN, stage_mouseDownHandler);
}
protected function stage_mouseDownHandler(event:MouseEvent):void
{
if (!isChildOf(event.target as DisplayObject))
deselectAll();
}
override public function addChildAt(child:DisplayObject, index:int):DisplayObject
{
if (child is UIComponent)
{
UIComponent(child).addEventListener(MouseEvent.MOUSE_DOWN, child_mouseDownHandler);
UIComponent(child).addEventListener(MouseEvent.MOUSE_UP, child_mouseUpHandler);
}
return super.addChildAt(child, index);
}
override protected function createChildren():void
{
super.createChildren();
selectionLayer = new Canvas();
selectionLayer.percentWidth = selectionLayer.percentHeight = 100;
selectionLayer.alpha = 0.5;
super.addChildAt(selectionLayer, 0);
}
protected function child_mouseDownHandler(event:MouseEvent):void
{
var target:UIComponent = event.currentTarget as UIComponent;
if (!isSelected(target))
{
if (!event.ctrlKey)
deselectExcept(target);
select(target);
target.addEventListener(MouseEvent.MOUSE_MOVE, child_mouseMoveHandler);
}
else
{
if (event.ctrlKey)
deselect(target);
else
target.addEventListener(MouseEvent.MOUSE_MOVE, child_mouseMoveHandler);
}
}
protected function child_mouseMoveHandler(event:MouseEvent):void
{
var target:UIComponent = event.currentTarget as UIComponent;
selectionLayer.startDrag();
isDragging = true;
target.removeEventListener(MouseEvent.MOUSE_MOVE, child_mouseMoveHandler);
}
protected function child_mouseUpHandler(event:MouseEvent):void
{
var target:UIComponent = event.currentTarget as UIComponent;
target.removeEventListener(MouseEvent.MOUSE_MOVE, child_mouseMoveHandler);
if (isDragging)
{
if (target.parent == selectionLayer)
{
selectionLayer.stopDrag();
isDragging = false;
for (var i:int = 0; i < selectionLayer.numChildren; i++)
{
var child:UIComponent = selectionLayer.getChildAt(i) as UIComponent;
child.move(child.x + selectionLayer.x, child.y + selectionLayer.y);
}
selectionLayer.move(0,0);
}
}
}
private function isSelected(target:DisplayObject):Boolean
{
return target.parent == selectionLayer;
}
private function isChildOf(obj:DisplayObject):Boolean
{
var p:DisplayObject = obj.parent;
while (p)
{
if (p == this)
return true;
p = p.parent;
}
return false;
}
private function select(target:DisplayObject):void
{
if (isSelected(target))
return;
super.removeChild(target);
selectionLayer.addChild(target);
}
private function deselect(target:DisplayObject):void
{
if (!isSelected(target))
return;
selectionLayer.removeChild(target);
super.addChild(target);
}
private function deselectExcept(target:DisplayObject):void
{
var children:Array = selectionLayer.getChildren();
for each (var child:DisplayObject in children)
{
if (target != child)
deselect(child);
}
}
private function deselectAll():void
{
deselectExcept(null);
}
}
}
示例应用程序:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns="*"
minWidth="955" minHeight="600">
<DraggableCanvas width="100%" height="100%">
<mx:Panel x="10" y="10"/>
<mx:Panel x="150" y="10"/>
<mx:Panel x="300" y="10"/>
</DraggableCanvas>
</s:Application>
另一个建议是,由于您使用的是 Flex 4.5,因此也建议使用子类化SkinnableDataContainer
或。ListBase
那些带有 ItemRenderer 的组件提供了很好的功能。但如果您不熟悉火花组件,请不要介意。
您可以从阅读和研究一个提供 Elixir 核心功能的开源应用程序开始。该项目是ObjectHandles