fmi*_*fmi 18 android drag-and-drop imageview android-layout
我正在尝试在android studio中创建一个简单的拖放图像.我可以让图像在屏幕上拖动,一旦我释放它就会消失.在控制台中,我收到"报告丢弃结果:false"
这是我的代码:
ImageView mImageView;
String mString;
private android.widget.RelativeLayout.LayoutParams mLayoutParams;
mImageView.setOnLongClickListener(new View.OnLongClickListener(){
@Override
public boolean onLongClick(View v){
ClipData.Item item = new ClipData.Item((CharSequence)v.getTag());
String[] mimeTypes = {
ClipDescription.MIMETYPE_TEXT_PLAIN
};
ClipData dragData = new ClipData(v.getTag().toString(), mimeTypes, item);
View.DragShadowBuilder myShadow = new View.DragShadowBuilder(mImageView);
v.startDrag(dragData, myShadow, null, 0);
return true;
}
});
mImageView.setOnDragListener(new View.OnDragListener() {
@Override
public boolean onDrag(View v, DragEvent event) {
switch(event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
mLayoutParams = (RelativeLayout.LayoutParams)v.getLayoutParams();
Log.d(mString, "Action is DragEvent.ACTION_DRAG_STARTED");
// Do nothing
break;
case DragEvent.ACTION_DRAG_ENTERED:
Log.d(mString, "Action is DragEvent.ACTION_DRAG_ENTERED");
int x_cord = (int) event.getX();
int y_cord = (int) event.getY();
break;
case DragEvent.ACTION_DRAG_EXITED :
Log.d(mString, "Action is DragEvent.ACTION_DRAG_EXITED");
x_cord = (int) event.getX();
y_cord = (int) event.getY();
mLayoutParams.leftMargin = x_cord;
mLayoutParams.topMargin = y_cord;
v.setLayoutParams(mLayoutParams);
break;
case DragEvent.ACTION_DRAG_LOCATION :
Log.d(mString, "Action is DragEvent.ACTION_DRAG_LOCATION");
x_cord = (int) event.getX();
y_cord = (int) event.getY();
break;
case DragEvent.ACTION_DRAG_ENDED :
Log.d(mString, "Action is DragEvent.ACTION_DRAG_ENDED");
// Do nothing
break;
case DragEvent.ACTION_DROP:
Log.d(mString, "ACTION_DROP event");
// Do nothing
break;
default: break;
}
return true;
}
});
mImageView.setOnTouchListener(new View.OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
ClipData data = ClipData.newPlainText("", "");
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(mImageView);
mImageView.startDrag(data, shadowBuilder, mImageView, 0);
mImageView.setVisibility(View.INVISIBLE);
return true;
} else {
return false;
}
}
});
}
Run Code Online (Sandbox Code Playgroud)
}
编辑:更改了一个如何使用onTouch移动RelativeLayout中包含的所有视图的工作示例.我认为onDrag事件更适用于拖放数据项,而不是移动视图.
public class MainActivity extends AppCompatActivity implements View.OnTouchListener {
private RelativeLayout mRelLay;
private float mInitialX, mInitialY;
private int mInitialLeft, mInitialTop;
private View mMovingView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRelLay = (RelativeLayout) findViewById(R.id.relativeLayout);
for (int i = 0; i < mRelLay.getChildCount(); i++)
mRelLay.getChildAt(i).setOnTouchListener(this);
}
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
RelativeLayout.LayoutParams mLayoutParams;
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
mMovingView = view;
mLayoutParams = (RelativeLayout.LayoutParams) mMovingView.getLayoutParams();
mInitialX = motionEvent.getRawX();
mInitialY = motionEvent.getRawY();
mInitialLeft = mLayoutParams.leftMargin;
mInitialTop = mLayoutParams.topMargin;
break;
case MotionEvent.ACTION_MOVE:
if (mMovingView != null) {
mLayoutParams = (RelativeLayout.LayoutParams) mMovingView.getLayoutParams();
mLayoutParams.leftMargin = (int) (mInitialLeft + motionEvent.getRawX() - mInitialX);
mLayoutParams.topMargin = (int) (mInitialTop + motionEvent.getRawY() - mInitialY);
mMovingView.setLayoutParams(mLayoutParams);
}
break;
case MotionEvent.ACTION_UP:
mMovingView = null;
break;
}
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
给出的代码有一个问题很容易解决.的OnDragListener()应为目的地(或任何可能的目的地)图来设定.所以OnLongClickListener()和OnTouchListener()在源视图设置,imageView那么就应该imageView2为OnDragListener().这是一个很长的解释,但应该是一个简单的解决方案.
请参阅拖放示例.
如果正确完成,其余的解决方案将更加复杂(但是,有一个解决方法).
开始拖动时,基本上您需要将图像复制到剪贴板,然后将其粘贴到拖放视图中.这需要创建一个ContentProvider然后使用ContentResolver(链接).
剪贴板文档:ClipData
我有未来计划为应用程序执行此操作,但这不会很快发生,所以,不幸的是,我将无法提供任何代码.
但是,有一种解决方法更少涉及.
在可能被移动的任何图像上设置标记.
imageView.setTag("ImageTag1");
Run Code Online (Sandbox Code Playgroud)
在onLongClick(),设置item和dragData在问题中完成.
然后OnDragListener(),读取标签,确定要删除的图像,然后将该图像设置为视图.像这样的东西:
case DragEvent.ACTION_DROP:
ClipData.Item item = event.getClipData().getItemAt(0);
CharSequence dragData = item.getText();
if(dragData.equals("ImageTag1")) {
// this gets jpg image from "drawable" folder,
// set ImageView appropriately for your usage
((ImageView)v).setImageResource(R.drawable.image1);
} else if(dragData.equals("ImageTag2")) {
((ImageView)v).setImageResource(R.drawable.image2);
}
break;
Run Code Online (Sandbox Code Playgroud)
在"ACTION_DRAG_EXITED"的情况下,您还需要执行类似的操作.如果将图像放在无效区域中,则会将图像放回原始视图.