kamal
kamal

Reputation: 291

How to draw a line from the source to the destination of a drag and drop operation?

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

Answers (1)

user
user

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

Related Questions