我正在开发一个Android应用程序,用户可以购买建筑物,这些建筑物是实现拖放api的图像按钮。我的问题是,当用户购买两个建筑物时,比如colonyHutOne和colonyHutTwo,存在一个问题,x和y坐标保存在onDrag中。在我的onDrag中,我传递了onDragListener中的建筑物编号,所以我知道我在onDrag类中处理的是什么建筑物。这样我就可以将坐标保存到适当的建筑物中。问题在于,无论我传递到onDrag的建筑物编号是什么,最近创建的建筑物都是采用坐标的建筑物。在onDrag中,它每次都会接收第二个建筑物,即使它是第一个被拖动的建筑物(建筑物的第一个)。我不知道这是否与传递给onDrag的上下文有关,或者是因为在拖拽之前声明了onDragListeners所以它只需要最后创建的图像按钮。我不知道如何解决这个问题。请帮忙。
以下是设置两个建筑物的拖拽监听器的代码:
findViewById(R.id.topHalf).setOnDragListener(new ColonyHutDrag(getApplicationContext(), 1));
findViewById(R.id.bottomHalf).setOnDragListener(new ColonyHutDrag(getApplicationContext(), 1));
FrameLayout.LayoutParams param1 = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
newColonyHutFrame.addView(newColonyHutOne, param1);
findViewById(R.id.topHalf).setOnDragListener(new ColonyHutDrag(getApplicationContext(), 2));
findViewById(R.id.bottomHalf).setOnDragListener(new ColonyHutDrag(getApplicationContext(), 2));
FrameLayout.LayoutParams param1 = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
newColonyHutFrame.addView(newColonyHutTwo, param1);
这是onDrag类:
public class ColonyHutDrag implements OnDragListener
{
SharedPreferences prefs;
Context passedContext;
Database data;
int buildingNum = 0;
public ColonyHutDrag(Context applicationContext, int num)
{
passedContext = applicationContext;
buildingNum = num;
}//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();
if (buildingNum == 1)
{
data.colonyHutOneXEntry(x);
data.colonyHutOneYEntry(y);
Toast.makeText(passedContext, "Going in1 -> x: " + x + " y: " + y, Toast.LENGTH_SHORT).show();
}//end if
else if (buildingNum == 2)
{
data.colonyHutTwoXEntry(x);
data.colonyHutTwoYEntry(y);
Toast.makeText(passedContext, "Going in2 -> x: " + x + " y: " + y, Toast.LENGTH_SHORT).show();
}//end else if
data.close();
//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
这是用于拖放的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
我非常感谢任何帮助。我不知道如何解决这个问题。这几乎就像处理第二座建筑物一样,然后第一座建筑物再也无法被引用。 谢谢你们。
编辑:
BuildingsClick类中的代码
//find which building is being dragged
if (v.getTag() == "NewColonyHutOne")
{
ColonyHutDrag.setType(ColonyHutOneDrag.getType());
}//end if
else if (v.getTag() == "NewColonyHutTwo")
{
ColonyHutDrag.setType(ColonyHutTwoDrag.getType());
}//end if
ColonyHutOneDrag类的代码:
public class ColonyHutOneDrag extends ColonyHut
{
@Override
public int getType()
{
return 1;
}//end getType
}//end ColonyHutOneDrag
ColonyHutTwoDrag类的代码与第一个类相同,但返回2.
这是ColonyHutDrag中的getType:
public void setType(int type)
{
buildingNum = type;
}//end setType
答案 0 :(得分:1)
您错误地再次指定了OnDragListener
。
你不能
findViewById(R.id.topHalf).setOnDragListener(new ColonyHutDrag(getApplicationContext(), 1));
findViewById(R.id.bottomHalf).setOnDragListener(new ColonyHutDrag(getApplicationContext(), 1));
FrameLayout.LayoutParams param1 = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
然后
findViewById(R.id.topHalf).setOnDragListener(new ColonyHutDrag(getApplicationContext(), 2));
findViewById(R.id.bottomHalf).setOnDragListener(new ColonyHutDrag(getApplicationContext(), 2));
FrameLayout.LayoutParams param1 = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
原因是因为你的第二个电话会覆盖你的第一个电话,你永远不会听到要拖动的小屋类型1,因为你在你的构造函数中传递了你正在听的小屋。
解决方法是改变你的听众分配,如下所示:
findViewById(R.id.topHalf).setOnDragListener(new ColonyHutDrag(getApplicationContext()));
findViewById(R.id.bottomHalf).setOnDragListener(new ColonyHutDrag(getApplicationContext());
FrameLayout.LayoutParams param1 = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
我们将制作一个抽象类ColonyHut
,并定义public int getType();
。
除去ColonyHutListener
的构造函数,我们也不需要它。然后,如果您还没有一个名为ColonyHutOne
的课程,那么您将打造一个名为ColonyHut
的课程。在该课程中,您需要扩展getType()
,并定义public int getType()
{
return 1;
}
,如下所示:
ColonyHutDrag
然后我们将在setType()
类中定义一个名为public void setType(int type)
{
buildingNum = type;
}
的函数,如下所示:
ColonyHutOne
之后你想要ColonyHut
作为ColonyHut currentlySelectedHut = view.getHutFromView()
onTouchListener
,colonyHutDrag.setType(currentlySelectedHut.getType())
v.startDrag()
,然后再致电ColonyHutTwo
getType()
它应该有效。对view.getHutFromView()
执行相同操作,但显然您应该colonyHutDrag
返回2。
我将保留定义BuildingsClick
,并在{{1}}课程中显示{{1}}。毕竟一切都不是自由的: - )。