我正在创建一个应用程序,用户可以在其中购买作为图像按钮的建筑物,这些建筑物也实现了拖放API。目前,我遇到一个问题,我已经购买了两座建筑物:colonyHutOne和ColonyHutTwo。它们都有各自的onDrag类和onDragListeners设置。将其中一栋建筑物拖到某处时,第二栋建筑物的onDrag类即被调用(因为这是要购买并插入到视图中的最后一栋)。我不知道要阻止这个。应该是,当第一座建筑物移动时,它有其自己的onDrag调用,以便为正确的建筑物保存建筑物的坐标,但是由于它仅调用最近创建的buidling的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毫无意义。请帮助大家。

谢谢。

最佳答案

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

然后将SAME视图的OnDragListener设置为findViewById(R.id.topHalf),然后将其设置为new ColonyHutTwoDrag(getApplicationContext())。第二个调用将覆盖您的第一个调用,并且ColonyHutOneDrag中的代码永远不会运行,因为它不再是活动的侦听器。

相同的问题会影响您的视图findViewById(R.id.bottomHalf)

您要么要将两个侦听器组合为一个,让侦听器确定建筑物的类型,要么明确设置每个视图的OnDragListener。我建议采用前一种方法。

编辑:如果您的自定义类是正在传递的视图的子类,则将起作用。如果您的类不是子类视图,则可以在这些类之一中使用一个变量来区分另一个(例如,您要比较的String而不是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;
}

10-05 18:06