我正在创建一个应用程序,用户可以在其中购买作为图像按钮的建筑物,这些建筑物也实现了拖放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毫无意义。请帮助大家。
谢谢。
最佳答案
我相信您的问题是将OnDragListener
的findViewById(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;
}