调用错误的onDrag类

时间:2014-12-16 19:39:26

标签: java android drag-and-drop coordinates imagebutton

我正在创建一个应用程序,用户可以购买那些也是实现拖放API的图像按钮的建筑物。目前我遇到了一个问题,即我购买了2栋建筑物:colonyHutOne和colonyHutTwo。它们都有自己的onDrag类和onDragListeners单独设置。当某个建筑物被拖到某处时,第二个建筑物的onDrag类就是被调用的那个(因为它是最后一个被购买并插入到视图中的)。我不知道要阻止它。应该是当第一个建筑被移动时,它有自己的onDrag被调用,以便为正确的建筑保存建筑物的坐标,但由于它只是调用最近创建的建筑物的onDrag类,坐标没有正确保存。

以下是两个图像按钮的代码。 onDragListeners:

对于colonyHutOne建筑:

findViewById(R.id.topHalf).setOnDragListener(new ColonyHutOneDrag(getApplicationContext()));
findViewById(R.id.bottomHalf).setOnDragListener(new ColonyHutOneDrag(getApplicationContext()));
FrameLayout.LayoutParams  param1 = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
newColonyHutFrame.addView(newColonyHutOne, param1);

对于colonyHutTwo建筑:

findViewById(R.id.topHalf).setOnDragListener(new ColonyHutTwoDrag(getApplicationContext()));
findViewById(R.id.bottomHalf).setOnDragListener(new ColonyHutTwoDrag(getApplicationContext()));
FrameLayout.LayoutParams  param1 = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
newColonyHutFrame.addView(newColonyHutTwo, param1);

以下是onDrag类的代码:

对于colonyHutOne建筑:

public class ColonyHutOneDrag implements OnDragListener
{
SharedPreferences prefs;
Context passedContext;
Database data;

public ColonyHutOneDrag(Context applicationContext) 
{
    passedContext = applicationContext;
}//end constructor

@Override
public boolean onDrag(View v, DragEvent event) 
{
    float x = 0, y = 0;
    switch(event.getAction())
    {
        case DragEvent.ACTION_DRAG_STARTED:
            //drag has started
            break;

        case DragEvent.ACTION_DRAG_ENTERED:
            //being dragged
            break;

        case DragEvent.ACTION_DRAG_EXITED:
            //stop drag
            break;

        case DragEvent.ACTION_DRAG_LOCATION:
            //find drag location
            break;

        case DragEvent.ACTION_DROP:
            if (v == v.findViewById(R.id.bottomHalf))
            {
                //find position where dropped
                x = event.getX();
                y = event.getY();

                //save the coordinates that the building was dropped at
                data = new Database(passedContext);
                data.open();
                data.colonyHutOneXEntry(x);
                data.colonyHutOneYEntry(y);
                data.close();
                Toast.makeText(passedContext, "Going in1 -> x: " + x + " y: " + y, Toast.LENGTH_SHORT).show();

                //use this to fix building loadup glitch
                View view = (View) event.getLocalState();
                ViewGroup group = (ViewGroup) view.getParent();
                group.removeView(view);
                FrameLayout contain = (FrameLayout) v;
                contain.addView(view);
                view.setX(x - (view.getWidth()/2));
                view.setY(y - (view.getHeight()/2));
                view.setVisibility(View.VISIBLE);
            }//end if
            else
            {
                View view = (View) event.getLocalState();
                view.setVisibility(View.VISIBLE);
            }//end else
            break;

        default:
            break;
    }//end switch
    return true;
}//end onDrag function
}//end ColonyHutOneDrag class

对于colonyHutTwo建筑:

public class ColonyHutTwoDrag implements OnDragListener
{
SharedPreferences prefs;
Context passedContext;
Database data;

public ColonyHutTwoDrag(Context applicationContext) 
{
    passedContext = applicationContext;
}//end constructor

@Override
public boolean onDrag(View v, DragEvent event) 
{
    float x = 0, y = 0;
    switch(event.getAction())
    {
        case DragEvent.ACTION_DRAG_STARTED:
            //drag has started
            break;

        case DragEvent.ACTION_DRAG_ENTERED:
            //being dragged
            break;

        case DragEvent.ACTION_DRAG_EXITED:
            //stop drag
            break;

        case DragEvent.ACTION_DRAG_LOCATION:
            //find drag location
            break;

        case DragEvent.ACTION_DROP:
            if (v == v.findViewById(R.id.bottomHalf))
            {
                //find position where dropped
                x = event.getX();
                y = event.getY();

                //save the coordinates that the building was dropped at
                data = new Database(passedContext);
                data.open();
                data.colonyHutTwoXEntry(x);
                data.colonyHutTwoYEntry(y);
                data.close();
                Toast.makeText(passedContext, "Going in2 -> x: " + x + " y: " + y, Toast.LENGTH_SHORT).show();

                //use this to fix building loadup glitch
                View view = (View) event.getLocalState();
                ViewGroup group = (ViewGroup) view.getParent();
                group.removeView(view);
                FrameLayout contain = (FrameLayout) v;
                contain.addView(view);
                view.setX(x - (view.getWidth()/2));
                view.setY(y - (view.getHeight()/2));
                view.setVisibility(View.VISIBLE);
            }//end if
            else
            {
                View view = (View) event.getLocalState();
                view.setVisibility(View.VISIBLE);
            }//end else
            break;

        default:
            break;
    }//end switch
    return true;
}//end onDrag function
}//end ColonyHutTwoDrag class

这是用于开始拖动的onTouchListener:

public class BuildingsClick implements OnTouchListener 
{   
@Override
public boolean onTouch(View v, MotionEvent event) 
{
    ClipData.Item item = new ClipData.Item((CharSequence)v.getTag());

    String[] mimeTypes = { ClipDescription.MIMETYPE_TEXT_PLAIN }; 
    ClipData data = new ClipData(v.getTag().toString(), mimeTypes, item); 
    DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v); 

    v.startDrag(data, shadowBuilder, v, 0);
    v.setVisibility(View.INVISIBLE);

    return false;   
}//end onTouch function

}//end BuildingsClick class

对我来说,即使我拖动第一栋建筑物,每次都会调用第二栋建筑的onDrag。请帮帮我们。

感谢。

1 个答案:

答案 0 :(得分:1)

我相信,您的问题是,您将OnDragListener findViewById(R.id.topHalf)设置为new ColonyHutOneDrag(getApplicationContext())

然后,您在此之后将OnDragListener设置为findViewById(R.id.topHalf) new ColonyHutTwoDrag(getApplicationContext())ColonyHutOneDrag。第二个调用会覆盖您的第一个调用,而findViewById(R.id.bottomHalf)中的代码永远不会运行,因为它不再是主动侦听器。

同样的问题会影响您的观看次数OnDragListener

您要么将两个侦听器合并为一个,让侦听器决定它是哪种类型的建筑物,要么明确地设置每个视图的if(v instance of class)。我建议使用前一种方法。

编辑:如果您的自定义类是要传递的视图的子类,这将有效。如果您的类不是子类化视图,则可以使用其中一个类中的变量来区分其中一个(就像您比较的字符串而不是switch(((View)v.getParent()).getID()) { case R.id.topHalf: if(v instanceof ColonyHutOne) topHalfColonyOne(); else if(v instanceof ColonyHutTwo) topHalfColonyTwo(); break; case R.id.bottomHalf: if(v instanceof ColonyHutOne) bottomHalfColonyOne(); else if(v instanceof ColonyHutTwo) bottomHalfColonyTwo(); break; } )。

{{1}}