Reputation: 291
I've implemented a drag and drop system and now I want to draw a line from the source to destination. How can I draw that line? I already used an extension of the View
class, but it's not working. Here is my code:
public class TempDDActivity extends Activity implements OnTouchListener {
/** Called when the activity is first created. */
private View selected_item = null;
private int offset_x = 0;
private int offset_y = 0;
Boolean touchFlag=false;
boolean dropFlag=false;
LayoutParams imageParams;
ImageView imageDrop,image1,image2;
int crashX,crashY;
Drawable dropDrawable,selectDrawable;
Rect dropRect,selectRect;
int topy,leftX,rightX,bottomY;
int dropArray[];
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
ViewGroup container = (ViewGroup) findViewById(R.id.container);
imageDrop=(ImageView) findViewById(R.id.ImgDrop);
image1=(ImageView) findViewById(R.id.img);
image2=(ImageView) findViewById(R.id.img2);
container.setOnTouchListener(new View.OnTouchListener()
{
public boolean onTouch(View v, MotionEvent event)
{
if(touchFlag==true)
{
System.err.println("Display If Part ::->"+touchFlag);
switch (event.getActionMasked())
{
case MotionEvent.ACTION_DOWN :
topy=imageDrop.getTop();
leftX=imageDrop.getLeft();
rightX=imageDrop.getRight();
bottomY=imageDrop.getBottom();
System.err.println("Display Top-->"+topy);
System.err.println("Display Left-->"+leftX);
System.err.println("Display Right-->"+rightX);
System.err.println("Display Bottom-->"+bottomY);
//opRect.
break;
case MotionEvent.ACTION_MOVE:
crashX=(int) event.getX();
crashY=(int) event.getY();
System.err.println("Display Here X Value-->"+crashX);
System.err.println("Display Here Y Value-->"+crashY);
int x = (int) event.getX() - offset_x;
int y = (int) event.getY() - offset_y;
//int w = getWindowManager().getDefaultDisplay().getWidth() - 100;
//int h = getWindowManager().getDefaultDisplay().getHeight() - 100;
int w = getWindowManager().getDefaultDisplay().getWidth() - 50;
int h = getWindowManager().getDefaultDisplay().getHeight() - 10;
if (x > w)
x = w;
if (y > h)
y = h;
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(new ViewGroup.MarginLayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
lp.setMargins(x, y, 0, 0);
//Drop Image Here
if(crashX > leftX && crashX < rightX && crashY > topy && crashY < bottomY )
{
Drawable temp=selected_item.getBackground();
imageDrop.setBackgroundDrawable(temp);
imageDrop.bringToFront();
dropFlag=true;
selected_item.setVisibility(View.INVISIBLE);
}
//Drop Image Here
selected_item.setLayoutParams(lp);
break;
case MotionEvent.ACTION_UP:
//
touchFlag=false;
if(dropFlag==true)
{
dropFlag=false;
}
else
{
selected_item.setLayoutParams(imageParams);
}
break;
default:
break;
}
}else
{
System.err.println("Display Else Part ::->"+touchFlag);
}
return true;
}
});
image1.setOnTouchListener(this);
image2.setOnTouchListener(this);
}
public boolean onTouch(View v, MotionEvent event)
{
switch (event.getActionMasked())
{
case MotionEvent.ACTION_DOWN:
touchFlag=true;
offset_x = (int) event.getX();
offset_y = (int) event.getY();
selected_item = v;
imageParams=v.getLayoutParams();
break;
case MotionEvent.ACTION_UP:
selected_item=null;
touchFlag=false;
break;
default:
break;
}
return false;
}
}
Upvotes: 2
Views: 1790
Reputation: 87064
now I want to draw a line from source to destination
First you need to have a custom view for actually drawing the line. This would be the layout that wraps the ImageViews
, which in your case I think is a RelativeLayout
. That class would be something like:
public class DragObserverLayout extends RelativeLayout {
float startX, startY, stopX, stopY;
private Paint mPaint = new Paint();
private List<Rect> lines = new ArrayList<Rect>();
public DragObserverLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint.setColor(Color.GREEN);
mPaint.setStrokeWidth(2.0f);
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
final int count = lines.size();
for (int i = 0; i < count; i++) {
final Rect r = lines.get(i);
canvas.drawLine(r.left, r.top, r.right, r.bottom, mPaint);
}
}
public void addLine(Rect r) {
lines.add(r);
invalidate();
}
}
Then in the OnTouchListener
for the container where you do the drag operation you would simply do:
final int[] location = new int[2];
final DragObserverLayout container = (DragObserverLayout ) findViewById(R.id.container);
container.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if(touchFlag==true) {
switch (event.getActionMasked())
{
case MotionEvent.ACTION_DOWN :
//...
selected_item.getLocationOnScreen(location);
container.startX = location[0];
container.startY = location[1];
break;
case MotionEvent.ACTION_MOVE:
//...
selected_item.getLocationOnScreen(location);
break;
case MotionEvent.ACTION_UP:
// ...
// .. the item was dragged on the target
if (selected_item.getVisibility() != View.VISIBLE) {
Rect r = new Rect();
r.left = (int) container.startX;
r.top = (int) container.startY;
imageDrop.getLocationInWindow(location);
r.right = location[0];
r.bottom = location[1];
container.addLine(r);
}
This will draw a straight line from the initial position of the dragged ImageView
(top left point of the view) to the current position until the ImageView
is "dropped". If you want you could offset the start line's position to point to the real touched position by making some simple calculation in the onTouch
method for the ImageViews
. This also works as you have a full screen application covering the entire screen, otherwise you'll have to offset the return from getLocationOnScreen()
to take in consideration the status bar. If you want to keep the line on the screen after the drag operation finishes you'll need to store it in the container.
Upvotes: 1