gpt4 book ai didi

drag-and-drop - feathersui 在列表中拖放并连接两个列表

转载 作者:行者123 更新时间:2023-12-04 06:26:07 26 4
gpt4 key购买 nike

下面是我们在同一个基于列表的控件中拖放列表项的尝试。我们正在尝试使用 flex 组件镜像与“在同一控件中拖放”相同的功能:http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7cfd.html .

当用户重新排序列表时,每个索引将被写入一个文件,以便重新排序的列表在屏幕刷新时保持原样。

虽然我们可以渲染头像并将拖动的对象推到基于列表的控件的末尾,但我们无法将对象拖动到基于列表的控件中的特定索引。

我们可以做什么:google -> msn -> yahoo -> google

我们不能做的:google -> msn -> google -> yahoo

最后,如果您有任何关于如何为屏幕刷新存储重新排序的列表的想法,我们将不胜感激。

为了构建我们采纳了关于扩展列表的建议以及其他人的建议:mironcaius 和 Josh Tynjala:http://forum.starling-framework.org/topic/defaultlistitemrenderer-does-not-update-lableshttp://wiki.starling-framework.org/feathers/drag-drop (请参阅将显示对象本身添加为拖动数据)。

Main.as

package feathers.examples.dragDrop
{
import feathers.data.ListCollection;
import feathers.dragDrop.IDragSource;
import feathers.dragDrop.IDropTarget;
import feathers.themes.AeonDesktopTheme;

import starling.display.Sprite;
import starling.events.Event;

public class Main extends Sprite implements IDragSource, IDropTarget
{
public static var listCollection:ListCollection = new ListCollection([{playerName:"yahoo"},{playerName:"msn"},{playerName:"google"}]);

public function Main()
{
this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}

private function addedToStageHandler(event:Event):void
{
new AeonDesktopTheme();

var listTeam1:DragDropList = new DragDropList();
listTeam1.dataProvider = listCollection;
listTeam1.itemRendererProperties.labelField = "playerName";
listTeam1.itemRendererProperties.height = 38;
this.addChild(listTeam1);
//listTeam1.hasElasticEdges = false;
//listTeam1.addEventListener("changeTeam", changeTeamHandler);
}

/*private function changeTeamHandler(event:Event):void
{
//trace(event.target.data);
}*/
}
}

DragDropList.as

package feathers.examples.dragDrop
{
import feathers.controls.Label;
import feathers.controls.List;
import feathers.core.FeathersControl;
import feathers.dragDrop.DragData;
import feathers.dragDrop.DragDropManager;
import feathers.dragDrop.IDragSource;
import feathers.dragDrop.IDropTarget;
import feathers.events.DragDropEvent;

import starling.display.Quad;
import starling.events.Touch;
import starling.events.TouchEvent;
import starling.events.TouchPhase;

//[Event(name="changeTeam", type="Event")]

public class DragDropList extends List implements IDropTarget, IDragSource
{
public function DragDropList()
{
super();
addEventListener(TouchEvent.TOUCH, touchHandler);
addEventListener(DragDropEvent.DRAG_ENTER, dragEnterHandler);
addEventListener(DragDropEvent.DRAG_DROP, dragDropHandler);
addEventListener(DragDropEvent.DRAG_COMPLETE, dragCompleteHandler);
}

protected function touchHandler(event:TouchEvent):void
{
var touch:Touch = event.touches[0];
if(touch.phase == TouchPhase.BEGAN)
{
if(selectedItem)
{
var fc:FeathersControl = new FeathersControl();
fc.addChild(new Quad(150, 50, 0xFFFFFF));
var lbl:Label = new Label();
lbl.text = selectedItem["playerName"];
fc.addChild(lbl);
var dd:DragData = new DragData();
dd.setDataForFormat("playerFormat", selectedItem);
DragDropManager.startDrag(this, touch, dd, fc);
}
}
}

protected function dragEnterHandler(event:DragDropEvent, dragData:DragData):void
{
if(dragData.hasDataForFormat("playerFormat"))
{
DragDropManager.acceptDrag(this);
}
}

protected function dragDropHandler(event:DragDropEvent, dragData:DragData):void
{
if(dragData.hasDataForFormat("playerFormat"))
{
var obj:Object = dragData.getDataForFormat("playerFormat");
Main.listCollection.push(obj);
//dispatchEventWith("changeTeam", false, obj);
}
}

protected function dragCompleteHandler(event:DragDropEvent):void
{
if(event.isDropped)
{
Main.listCollection.removeItem(selectedItem);
}
}

}
}

最佳答案

我现在已经合理地实现了可拖动排序的羽毛列表。我确信它可以改进,作为 AS3/Starling/Feathers 的新手,我确信我会以不太理想的方式完成某些部分,但我对它的工作方式非常满意。

通过检测拖动是否接近列表的顶部/底部来控制滚动,在touchHandler中,启动较慢的滚动,或者超过列表的顶部/底部,开始更快的滚动。

希望它仍然对您有用,如有任何问题或改进建议,请随时回来!

泰德


此外,如果您对它们感兴趣,可以查看我在代码中使用的两个拖动 handle 图像: drag-handle.png drag-handle-down.png

Main.as

package feathers.examples.dragDrop
{
import feathers.controls.Button;
import feathers.controls.List;
import feathers.data.ListCollection;
import feathers.dragDrop.IDragSource;
import feathers.dragDrop.IDropTarget;
import feathers.themes.MetalWorksMobileTheme;

import starling.core.Starling;
import starling.display.Sprite;
import starling.events.Event;

public class Main extends Sprite implements IDragSource, IDropTarget
{
private var list:List;

public function Main()
{
this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}

private function addedToStageHandler(event:Event):void
{
new MetalWorksMobileTheme();

const PADDING:int = 100;

list = new List();
list.width = Starling.current.viewPort.width - (PADDING * 2);
list.height = Starling.current.viewPort.height - (PADDING * 2);
this.addChild( list );
list.y = PADDING;
list.x = PADDING;
list.itemRendererType = DragDropItemRenderer;

resetDefaultListData();

var resetButton:Button = new Button();
resetButton.label = "Reset List Data";
resetButton.addEventListener(Event.TRIGGERED, resetButtonHandler);
resetButton.nameList.add(Button.ALTERNATE_NAME_QUIET_BUTTON);
this.addChild(resetButton);
resetButton.validate();

resetButton.x = (Starling.current.viewPort.width / 2) - (resetButton.width / 2);
resetButton.y = Starling.current.viewPort.height - resetButton.height - (PADDING / 5);
}


private function resetButtonHandler(e:Event):void
{
resetDefaultListData();

}

private function resetDefaultListData():void
{
var defaultData:ListCollection = new ListCollection(
[
{text: 'Test Item 1' },
{text: 'Test Item 2' },
{text: 'Test Item 3' },
{text: 'Test Item 4' },
{text: 'Test Item 5' },
{text: 'Test Item 6' },
{text: 'Test Item 7' },
{text: 'Test Item 8' },
{text: 'Test Item 9' },
{text: 'Test Item 10' },
{text: 'Test Item 11' },
{text: 'Test Item 12' },
{text: 'Test Item 13' },
{text: 'Test Item 14' },
{text: 'Test Item 15' },
{text: 'Test Item 16' },
{text: 'Test Item 17' },
{text: 'Test Item 18' },
{text: 'Test Item 19' },
{text: 'Test Item 20' },
{text: 'Test Item 21' },
{text: 'Test Item 22' },
{text: 'Test Item 23' },
{text: 'Test Item 24' },
{text: 'Test Item 25' },
{text: 'Test Item 26' },
{text: 'Test Item 27' },
{text: 'Test Item 28' },
{text: 'Test Item 29' },
{text: 'Test Item 30' },
{text: 'Test Item 31' },
{text: 'Test Item 32' },
{text: 'Test Item 33' },
{text: 'Test Item 34' },
{text: 'Test Item 35' },
{text: 'Test Item 36' },
{text: 'Test Item 37' },
{text: 'Test Item 38' },
{text: 'Test Item 39' },
{text: 'Test Item 40' },
{text: 'Test Item 41' },
{text: 'Test Item 42' },
{text: 'Test Item 43' },
{text: 'Test Item 44' },
{text: 'Test Item 45' },
{text: 'Test Item 46' },
{text: 'Test Item 47' },
{text: 'Test Item 48' },
{text: 'Test Item 49' },
{text: 'Test Item 50' },
{text: 'Test Item 51' },
{text: 'Test Item 52' },
{text: 'Test Item 53' },
{text: 'Test Item 54' },
{text: 'Test Item 55' },
{text: 'Test Item 56' },
{text: 'Test Item 57' },
{text: 'Test Item 58' },
{text: 'Test Item 59' },
{text: 'Test Item 60' },
{text: 'Test Item 61' },
{text: 'Test Item 62' },
{text: 'Test Item 63' },
{text: 'Test Item 64' },
{text: 'Test Item 65' },
{text: 'Test Item 66' },
{text: 'Test Item 67' },
{text: 'Test Item 68' },
{text: 'Test Item 69' },
{text: 'Test Item 70' },
{text: 'Test Item 71' },
{text: 'Test Item 72' },
{text: 'Test Item 73' },
{text: 'Test Item 74' },
{text: 'Test Item 75' },
{text: 'Test Item 76' },
{text: 'Test Item 77' },
{text: 'Test Item 78' },
{text: 'Test Item 79' },
{text: 'Test Item 80' },
{text: 'Test Item 81' },
{text: 'Test Item 82' },
{text: 'Test Item 83' },
{text: 'Test Item 84' },
{text: 'Test Item 85' },
{text: 'Test Item 86' },
{text: 'Test Item 87' },
{text: 'Test Item 88' },
{text: 'Test Item 89' },
{text: 'Test Item 90' },
{text: 'Test Item 91' },
{text: 'Test Item 92' },
{text: 'Test Item 93' },
{text: 'Test Item 94' },
{text: 'Test Item 95' },
{text: 'Test Item 96' },
{text: 'Test Item 97' },
{text: 'Test Item 98' },
{text: 'Test Item 99' },
{text: 'Test Item 100' },

]);
list.dataProvider = defaultData;
}


}
}

DragDropItemRenderer.as

package feathers.examples.dragDrop
{
import flash.events.TimerEvent;
import flash.utils.Timer;

import feathers.controls.Label;
import feathers.controls.List;
import feathers.controls.renderers.IListItemRenderer;
import feathers.core.FeathersControl;
import feathers.dragDrop.DragData;
import feathers.dragDrop.DragDropManager;
import feathers.dragDrop.IDragSource;
import feathers.dragDrop.IDropTarget;
import feathers.events.DragDropEvent;

import starling.display.Button;
import starling.display.DisplayObject;
import starling.display.Quad;
import starling.display.Sprite;
import starling.events.Event;
import starling.events.Touch;
import starling.events.TouchEvent;
import starling.events.TouchPhase;
import starling.textures.Texture;
import starling.utils.Color;

public class DragDropItemRenderer extends FeathersControl implements IListItemRenderer, IDragSource, IDropTarget
{
[Embed(source="drag-handle.png")]
public static const DragHandle:Class;
[Embed(source="drag-handle-down.png")]
public static const DragHandleDown:Class;

private const LIST_ITEM_DRAG:String = "LIST_ITEM_DRAG";

public function DragDropItemRenderer()
{
//drag
this.addEventListener(DragDropEvent.DRAG_START, dragStartHandler);
this.addEventListener(DragDropEvent.DRAG_COMPLETE, dragCompleteHandler);

//drop
this.addEventListener(DragDropEvent.DRAG_ENTER, dragEnterHandler);
this.addEventListener(DragDropEvent.DRAG_EXIT, dragExitHandler);
this.addEventListener(DragDropEvent.DRAG_MOVE, dragMoveHandler);
this.addEventListener(DragDropEvent.DRAG_DROP, dragDropHandler);
}


//================================================================================================
//drag interface
//================================================================================================
private function dragStartHandler(event:DragDropEvent, dragData:DragData):void
{
//the drag was started with the call to DragDropManager.startDrag()
}

private function dragCompleteHandler(event:DragDropEvent, dragData:DragData):void
{
if(event.isDropped)
{
//the object successfully dropped at a valid location
}
stopScrolling();
}


private var carryOnScrolling:Boolean=false;
private var scrollDirection:String="";
private var scrollSpeed:String="";
private var scrollTimer:Timer;
private var avatarContainer:Sprite;
private var avatarBg:Quad;
private var avatarLabel:Label;

private const LIST_SCROLL_DETECT_HEIGHT:int = 30;

private const SCROLL_SIZE:int = 25;

private const SCROLL_SPEED_SLOW:String = "SLOW";
private const SCROLL_SPEED_FAST:String = "FAST";

private const SCROLL_DIRECTION_UP:String = "UP";
private const SCROLL_DIRECTION_DOWN:String = "DOWN";

private const SCROLL_TIME_MS_SLOW:int = 75;
private const SCROLL_TIME_MS_FAST:int = 25;
private var scrollSpeedMSToUse:int;

private function startScrollingList(direction:String, speed:String):void
{
scrollDirection = direction;
scrollSpeed = speed;
carryOnScrolling = true;

doScrollWorker();

if(scrollTimer != null)
{
scrollTimer.stop();
scrollTimer = null;
}


if(scrollSpeed == SCROLL_SPEED_FAST)
scrollSpeedMSToUse = SCROLL_TIME_MS_FAST;
else
scrollSpeedMSToUse = SCROLL_TIME_MS_SLOW;

scrollTimer = new Timer(scrollSpeedMSToUse);
scrollTimer.addEventListener(TimerEvent.TIMER, onScrollTimerHandler);
scrollTimer.start();
}

private function stopScrolling():void
{
carryOnScrolling = false;
}

private function onScrollTimerHandler(e:TimerEvent):void
{
if(carryOnScrolling)
{
doScrollWorker();
}
else
{
scrollTimer.stop();
scrollTimer = null;
}
}

private function doScrollWorker():void
{
const EXTRA_SCROLL_PADDING:int = 20;

var scrollSizeToUse:int = SCROLL_SIZE;

if(scrollDirection == SCROLL_DIRECTION_UP)
{
if((this.owner.verticalScrollPosition + scrollSizeToUse) < (this.owner.maxVerticalScrollPosition + EXTRA_SCROLL_PADDING))
{
this.owner.scrollToPosition(this.owner.horizontalScrollPosition, this.owner.verticalScrollPosition + scrollSizeToUse, (scrollSpeedMSToUse / 1000));
}
}
else
{
if((this.owner.verticalScrollPosition - scrollSizeToUse) > (this.owner.minVerticalScrollPosition - EXTRA_SCROLL_PADDING))
{
this.owner.scrollToPosition(this.owner.horizontalScrollPosition, this.owner.verticalScrollPosition - scrollSizeToUse, (scrollSpeedMSToUse / 1000));
}
}
}



private function touchHandler(event:TouchEvent):void
{
if(DragDropManager.isDragging)
{
//check if the drag is close enough to the top / bottom to start scrolling
var touchScrollTest:Touch = event.getTouch(this);

if(touchScrollTest)
{
if(touchScrollTest.globalY < this.owner.y)
{
startScrollingList(SCROLL_DIRECTION_DOWN, SCROLL_SPEED_FAST);
}
else if(touchScrollTest.globalY < this.owner.y + LIST_SCROLL_DETECT_HEIGHT)
{
startScrollingList(SCROLL_DIRECTION_DOWN, SCROLL_SPEED_SLOW);
}
else if(touchScrollTest.globalY > this.owner.y + this.owner.height)
{
startScrollingList(SCROLL_DIRECTION_UP, SCROLL_SPEED_FAST);
}
else if(touchScrollTest.globalY > this.owner.y + this.owner.height - LIST_SCROLL_DETECT_HEIGHT)
{
startScrollingList(SCROLL_DIRECTION_UP, SCROLL_SPEED_SLOW);
}
else
{
stopScrolling();
}
}

//one drag at a time, please
return;
}
if(this._touchID >= 0)
{
var touch:Touch = event.getTouch(this._draggedObject, null, this._touchID);
if(touch.phase == TouchPhase.MOVED)
{
this._touchID = -1;

avatarContainer = new Sprite();

const AVATAR_X_OFFSET:int = 75;

avatarBg = new Quad(this.width - AVATAR_X_OFFSET, this.height, starling.utils.Color.LIME);
avatarBg.alpha = 0.25;

avatarLabel = new Label();
avatarLabel.x = this._label.x;
avatarLabel.y = this._label.y;
avatarLabel.width = this._label.width;
avatarLabel.height = this._label.height;
avatarLabel.text = this._label.text;

avatarContainer.addChild(avatarBg);
avatarContainer.addChild(avatarLabel);

var dragData:DragData = new DragData();
dragData.setDataForFormat(LIST_ITEM_DRAG, this._data);
DragDropManager.startDrag(this, touch, dragData, avatarContainer, -avatarLabel.width + 75, 0);
}
else if(touch.phase == TouchPhase.ENDED)
{
stopScrolling();
this._touchID = -1;
this._bgQuad.color = starling.utils.Color.RED;
}
}
else
{
touch = event.getTouch(this, TouchPhase.BEGAN);
if(!touch || touch.target == this || touch.target == this._background)
{
return;
}

this._touchID = touch.id;
this._draggedObject = touch.target;
}
event.stopPropagation();

}


private var _background:Quad;
private var _touchID:int = -1;
private var _draggedObject:DisplayObject;

//================================================================================================



//================================================================================================
//drop interface
//================================================================================================
private function dragEnterHandler(event:DragDropEvent, dragData:DragData):void
{
if(!dragData.hasDataForFormat(LIST_ITEM_DRAG))
{
return;
}
DragDropManager.acceptDrag(this);
}

private function dragMoveHandler(event:DragDropEvent, dragData:DragData):void
{
var dataBeingDragged:Object = dragData.getDataForFormat(LIST_ITEM_DRAG);
if(dataBeingDragged != this._data)
{
if(event.localY < (this.height / 2))
{
this._hiliteTop.visible = true;
this._hiliteBottom.visible = false;
}
else
{
this._hiliteTop.visible = false;
this._hiliteBottom.visible = true;
}
}
}

private function dragExitHandler(event:DragDropEvent, dragData:DragData):void
{
this._label.text = this._data.text;
this._hiliteTop.visible = false;
this._hiliteBottom.visible = false;
}

private function dragDropHandler(event:DragDropEvent, dragData:DragData):void
{
var dataBeingDragged:Object = dragData.getDataForFormat(LIST_ITEM_DRAG);
if(dataBeingDragged != this._data)
{
this.owner.dataProvider.removeItem(dataBeingDragged);

var indexToDragTo:int = this.owner.dataProvider.getItemIndex(this.data);

if(this._hiliteBottom.visible)
indexToDragTo++;

this.owner.dataProvider.addItemAt(dataBeingDragged, indexToDragTo);

this._hiliteTop.visible = false;
this._hiliteBottom.visible = false;
}

stopScrolling();
}
//================================================================================================




//================================================================================================
//Item renderer code
//================================================================================================
protected var _index:int = -1;

public function get index():int
{
return this._index;
}

public function set index(value:int):void
{
if(this._index == value)
{
return;
}
this._index = value;
this.invalidate(INVALIDATION_FLAG_DATA);
}

protected var _owner:List;

public function get owner():List
{
return this._owner;
}

public function set owner(value:List):void
{
if(this._owner == value)
{
return;
}
this._owner = value;
this.invalidate(INVALIDATION_FLAG_DATA);
}

protected var _data:Object;

public function get data():Object
{
return this._data;
}

public function set data(value:Object):void
{
if(this._data == value)
{
return;
}
this._data = value;
this.invalidate(INVALIDATION_FLAG_DATA);
}

protected var _isSelected:Boolean;

public function get isSelected():Boolean
{
return this._isSelected;
}

public function set isSelected(value:Boolean):void
{
if(this._isSelected == value)
{
return;
}
this._isSelected = value;
this.invalidate(INVALIDATION_FLAG_SELECTED);
this.dispatchEventWith(Event.CHANGE);
}
protected var _label:Label;
protected var _bgQuad:Quad;
protected var _hiliteTop:Quad;
protected var _hiliteBottom:Quad;
protected var _dragHandle:Quad;
protected var _dragHandleButton:starling.display.Button;

override protected function initialize():void
{
this._bgQuad = new Quad(1, 1, starling.utils.Color.SILVER);
this._bgQuad.alpha = 0.5;
this.addChild(_bgQuad);

this._label = new Label();
this.addChild(this._label);

this._hiliteTop = new Quad(100, 2, starling.utils.Color.YELLOW);
this._hiliteTop.visible = false;
this.addChild(_hiliteTop);
this._hiliteBottom = new Quad(100, 2, starling.utils.Color.YELLOW);
this._hiliteBottom.visible = false;
this.addChild(_hiliteBottom);

var dragHandleTexture:Texture = Texture.fromBitmap(new DragHandle());
var dragHandleDownTexture:Texture = Texture.fromBitmap(new DragHandleDown());
_dragHandleButton = new starling.display.Button(dragHandleTexture, "", dragHandleDownTexture);
this.addChild(_dragHandleButton);

_dragHandleButton.addEventListener(TouchEvent.TOUCH, touchHandler);
}

protected function commitData():void
{
if(this._data)
{
this._label.text = this._data.text;
}
else
{
this._label.text = null;
}
}

protected var _padding:Number = 5;

public function get padding():Number
{
return this._padding;
}

public function set padding(value:Number):void
{
if(this._padding == value)
{
return;
}
this._padding = value;
this.invalidate(INVALIDATION_FLAG_LAYOUT);
}
protected function autoSizeIfNeeded():Boolean
{
var needsWidth:Boolean = isNaN(this.explicitWidth);
var needsHeight:Boolean = isNaN(this.explicitHeight);
if(!needsWidth && !needsHeight)
{
return false;
}

this.explicitHeight = 50;
this._label.width = this.explicitWidth - 2 * this._padding;
this._label.height = this.explicitHeight - 2 * this._padding;
this._label.validate();

var newWidth:Number = this.explicitWidth;
if(needsWidth)
{
newWidth = this._label.width + 2 * this._padding;
}
var newHeight:Number = this.explicitHeight;
if(needsHeight)
{
newHeight = this._label.height + 2 * this._padding;
}
return this.setSizeInternal(newWidth, newHeight, false);
}
override protected function draw():void
{
var dataInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_DATA);

if(dataInvalid)
{
this.commitData();
}

this.autoSizeIfNeeded();
this.layoutChildren();
}

protected function layoutChildren():void
{
this._label.width = this.actualWidth - (2 * this._padding);
this._label.height = this.actualHeight - (2 * this._padding);
this._label.x = this._padding;
this._label.y = 15;//(this.actualHeight / 2) - (this._label.height / 2);

this._bgQuad.x = this._padding;
this._bgQuad.y = this._padding;
this._bgQuad.width = this.actualWidth - (2 * this._padding);
this._bgQuad.height = this.actualHeight - (2 * this._padding);

this._hiliteTop.x = 0;
this._hiliteBottom.x = 0;
this._hiliteTop.y = 0;
this._hiliteBottom.y = this.height; //this.height - this._hiliteBottom.height;

this._hiliteTop.width = this.width;
this._hiliteBottom.width = this.width;

this._dragHandleButton.x = this.width - this._dragHandleButton.width;
this._dragHandleButton.y = (this.height / 2) - (this._dragHandleButton.height / 2);

}

//================================================================================================

}
}

关于drag-and-drop - feathersui 在列表中拖放并连接两个列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23399614/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com