2

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;
    }
}
user
  • 86,916
  • 18
  • 197
  • 190
kamal
  • 290
  • 3
  • 20

1 Answers1

1

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.

user
  • 86,916
  • 18
  • 197
  • 190
  • i want to draw a line after ACTION_UP: Caused by: java.lang.ClassCastException: android.widget.RelativeLayout – kamal Mar 21 '13 at 10:05
  • @kamal Do you want to draw a line between the dragged `ImageView` and the drop `ImageView` if the user drags the first one on top of the other? This line should remain on the screen? Also what is with that exception? – user Mar 21 '13 at 10:20
  • simple thing, when i drag Imageview at destination then show a line between source and destincation , as like in example there is image1, when i pick image1 and leave at imageDrop then 1 simple line will show between these 2 images , at where initially image1,;;;;;;;;; and exception is at ....... final DragObserverLayout container = (DragObserverLayout ) findViewById(R.id.container); – kamal Mar 21 '13 at 10:27
  • @kamal See my edited answer. My code assumes that you use `DragObserverLayout` instead of the view you currently use for container in the layout file. – user Mar 21 '13 at 10:38
  • same exception 03-21 16:12:53.313: E/AndroidRuntime(4929): Caused by: java.lang.ClassCastException: android.widget.RelativeLayout – kamal Mar 21 '13 at 10:43
  • please enter in this room http://chat.stackoverflow.com/rooms/24164/discussion-between-rohit-and-tushar – kamal Mar 21 '13 at 10:45