拖放AS3:拖动包含动态和输入文本的mc时出现问题

时间:2010-11-13 09:52:34

标签: flash actionscript-3 drag-and-drop

简单的拖放应用程序,其中mc被拖出一个父mc并被放入另一个父mc 一切正常,直到我向mc添加了2个文本框 - 一个是由代码设置的不可选动态文本框(标签),另一个是用户可以修改的可选输入文本。

文本框会导致一些问题:

  1. 当用户将鼠标悬停在包含文本字段的mc部分(甚至是不可选择的文本?)时,手指光标会消失。
  2. 当用户试图通过无意中点击拖动两个文本区域内的任何位置来拖动mc时,会导致此错误: TypeError:错误#1034:类型强制失败:无法将flash.text :: TextField @ 2374a381转换为flash.display.MovieClip (两个文本框都出现相同的错误)
  3. 输入文本框可能会让用户感到困惑 - 他们有时会点击拖动,有时会点击修改?我认为输入文本需要明确是mc中的非点击拖动“区域”。 (希望有道理)
  4. 不确定,但是我可能需要在mc中创建一个覆盖区域,用于拖动点击检测?
    还有其他建议吗?

    以下是相关的代码:

    var itemArray:Array = [
                        {iname:"police",ititle:"POLICE OFFICER"},
                        {iname:"insurance_assessor",ititle:"INSURANCE ASSESSOR"},
                        {iname:"estimator",ititle:"ESTIMATOR"}
                        ];
    for (var i:int=0; i < itemArray.length; i++) 
    { 
     var itemname:String = itemArray[i].iname;
     var curritem:MovieClip = MovieClip(scrollitems.getChildByName(itemname)); 
     if (curritem != null) 
     { 
       curritem.ititle.text = itemArray[i].ititle;
       curritem.addEventListener(MouseEvent.MOUSE_DOWN, pickUp); 
       curritem.addEventListener(MouseEvent.MOUSE_UP, dropIt); 
       curritem.buttonMode = true; 
     }
    }
    
    function pickUp(event:MouseEvent):void
    {
      var dragIt:MovieClip = MovieClip(event.target);   //type casting
      var dragPoint:Point = dragIt.parent.localToGlobal(new Point(dragIt.x,dragIt.y));
      dragIt.parent.removeChild(dragIt); // remove item from current parent mc
      stage.addChild(dragIt); //temp add to stage
      dragIt.x = dragPoint.x;
      dragIt.y = dragPoint.y;
      dragIt.startDrag();
    }
    

3 个答案:

答案 0 :(得分:3)

你遇到的问题是Textfields是mouseEnabled。标签字段mouseEnabled属性应设置为false,对于其他TextField我可以想到两个解决方案。

  • 更简单的方法(正如您已经提到的)可能是在您的mc中创建一个可拖动的hitArea,类似于桌面上的窗口顶部,您可以将您的事件侦听器添加到此区域以便mc只能从那里拖走。

  • 第二种方法可能是在MouseDown上将mc的mouseChildren属性设置为false,并在MouseUp上设置为true。这不应该干扰用户在输入文本字段中输入文本。

答案 1 :(得分:2)

只需将事件监听器(focus_in&amp; out)添加到文本字段,制作函数并删除focus_in上拖动的事件,然后将它们放回focus_out。 像这样:

drag.textFieldName.addEventListener(FocusEvent.FOCUS_IN, setFIn);
drag.textFieldName.addEventListener(FocusEvent.FOCUS_OUT, setFOut);
function setFIn(focus:FocusEvent):void {
    var item = focus.target.parent;
    item.removeEventListener(MouseEvent.MOUSE_DOWN, MCdrag_press);
    item.removeEventListener(MouseEvent.MOUSE_UP, MCdrag_release);
}
function setFOut(focus:FocusEvent):void {
    var item = focus.target.parent;
    item.addEventListener(MouseEvent.MOUSE_DOWN, MCdrag_press);
    item.addEventListener(MouseEvent.MOUSE_UP, MCdrag_release);
}

如果用户触摸文本区域,则不会错误地拖动它,甚至不会显示闪存错误。 干杯

答案 2 :(得分:0)

问题源于MOUSE_DOWN用于开始编辑TextFields并开始拖动MovieClip。因此,如果您可以区分被点击的对象是否是TextField,您可以摆脱这种歧义,如下所示:

var curritem:MovieClip = new MovieClip();
curritem.Width = 125;
curritem.Height = 25;

var fontFormat:TextFormat = new TextFormat( );
fontFormat.font = "Arial";

var tf:TextField = new TextField();
tf.type = TextFieldType.INPUT;
tf.setTextFormat(fontFormat);
tf.text = "Some Text";

curritem.addChild(tf);

curritem.addEventListener(MouseEvent.MOUSE_DOWN, startMove); 
curritem.addEventListener(MouseEvent.MOUSE_UP, stopMove); 

function startMove(act:MouseEvent):void
{
    if (getQualifiedClassName(act.target) == "flash.text::TextField")
    {
        trace("text is down");
        act.target.parent.startDrag();
    }
    else
    {
            trace("movieclip is down");
        act.target.startDrag();
    }


}

function stopMove(act:MouseEvent):void
{
    if (getQualifiedClassName(act.target) == "flash.text::TextField")
    {
        trace("text is up");
        act.target.parent.stopDrag();

    }
    else
    {
        trace("movieclip is up");
        act.target.stopDrag();
    }

}