我正在创建一个应用程序,用户可以购买那些也是实现拖放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。请帮帮我们。
感谢。
答案 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}}