我想用拖放的方法在用户拖放的屏幕上放置几个视图对象。但这在第一次使用时出现了奇怪的错误,它没有放在用户离开的地方,而是放在一个非常不相关的地方,有时甚至在屏幕之外。但是,第一次使用后,就没有这个问题了。它把它放在我想要的地方。这个问题的根源是什么?
setOnDragListener()
contentTableLayout.setOnDragListener(new View.OnDragListener() {
@Override
public boolean onDrag(View view, DragEvent event) {
Log.i(TAG, " event.getAction(): " + event.getAction() + " getView: ID: " + view.getId() + " getContext: " + view.getContext());
String getImageFileNameSelectedRoom = getImageFileNameToRoom();
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
if (event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
View draggedView = (View) event.getLocalState();
initialX = draggedView.getX();
initialY = draggedView.getY();
Log.i(TAG, "ACTION_DRAG_STARTED -> initialX: " + initialX + " initialY: " + initialY);
changeBackgroundColorOnDrag(view, "#664CAF50", true);
return true;
}
return event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN);
case DragEvent.ACTION_DRAG_ENTERED:
changeBackgroundColorOnDrag(view, "#664CAF50", true);
return true;
case DragEvent.ACTION_DRAG_LOCATION:
return true;
case DragEvent.ACTION_DRAG_EXITED:
changeBackgroundColorOnDrag(view, "#66D32121", true);
return true;
case DragEvent.ACTION_DROP:
Log.i(TAG, "ACTION_DROP -> ");
View draggedView = (View) event.getLocalState();
ViewGroup owner = (ViewGroup) draggedView.getParent();
owner.removeView(draggedView);
FrameLayout container = (FrameLayout) view;
container.addView(draggedView);
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(draggedView);
Point shadowSize = new Point();
shadowBuilder.onProvideShadowMetrics(shadowSize, new Point());
int x = (int) event.getX() - draggedView.getMeasuredWidth() / 2;
int y = (int) event.getY() - draggedView.getMeasuredHeight() / 2;
draggedView.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT));
Log.i(TAG, "ACTION_DROP -> " + x + " y: " + y);
draggedView.setX(x);
draggedView.setY(y);
draggedView.setVisibility(View.VISIBLE);
return true;
case DragEvent.ACTION_DRAG_ENDED:
if (!event.getResult()) {
if (getImageFileNameSelectedRoom != null) {
File targetFile = findImageFile(getImageFileNameSelectedRoom);
if (targetFile != null) {
Bitmap bitmap = BitmapFactory.decodeFile(targetFile.getAbsolutePath());
BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), bitmap);
((FrameLayout) view).setBackground(bitmapDrawable);
view.invalidate();
} else {
Log.e(TAG, "Resim dosyası bulunamadı.");
}
}
View droppedView = (View) event.getLocalState();
droppedView.setVisibility(View.VISIBLE);
}
return true;
default:
break;
}
return false;
}
});
setOnLongListener()
mainView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
ClipData.Item item = new ClipData.Item((CharSequence) view.getTag());
ClipData dragData = new ClipData((CharSequence) view.getTag(), new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN}, item);
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
Log.i(TAG, " getXFromView: " + view.getX() + "getYFromView: " + view.getY());
view.startDrag(dragData, shadowBuilder, view, 0);
return true;
}
});
在上面的代码中,第一个拖放操作不正确。当我尝试下面的代码时,第一次拖放操作没问题,但这次接下来的就坏了。
case DragEvent.ACTION_DROP:
// ...
int x = (int) (initialX + event.getX() - shadowSize.x / 2);
int y = (int) (initialY + event.getY() - shadowSize.y / 2);
//initialX and initialY values come from the ACTION_DRAG_STARTED case.
// ...
确保窗口(驱动程序)最大化
在其他来源的帮助下解决了问题。
当我删除下面的代码时,所有拖放功能都可以正常工作:
draggedView.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT));