user622578
user622578

Reputation:

How to make Drag & Drop Button in Android

I want to make a drag and drop button. Drag it where you want it to do and it stays there. Below code only scales the button, doesn't change its position.

package com.dynamic;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.dynamic.R;
import com.dynamic.R.layout;


public class dy extends Activity {
     int status;
     private FrameLayout layout;
     ImageView image;
     Button b;
     LayoutParams params;
     public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.frm);
            final Button tv=(Button)findViewById(R.id.txt_birth);
            tv.setDrawingCacheEnabled(true);

            layout = (FrameLayout) findViewById(R.id.frm);
            params = new LayoutParams(100,100);


            params = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
            tv.setOnTouchListener(new View.OnTouchListener(){

        @Override
        public boolean onTouch(View v, MotionEvent me) {
            // TODO Auto-generated method stub

            if (me.getAction() == MotionEvent.ACTION_DOWN) {
                System.out.println("up");
                status = 0;

            }
            if (me.getAction() == MotionEvent.ACTION_UP) {
                status = 1;
                //Log.i("Drag", "Stopped Dragging");
            } else if (me.getAction() == MotionEvent.ACTION_MOVE) {
                if (status == 0) {
                    System.out.println("Dragging");

                    tv.setPadding((int) me.getRawX(), (int) me.getRawY(), 0, 0);
                //  b.setPadding(0,50,0,0);
                    tv.invalidate();

                }
            }
            return false;
        }

    });
}
}

Upvotes: 14

Views: 30043

Answers (4)

0xAffe
0xAffe

Reputation: 1206

Maybe the answers should be improved, because this question is still very prominent when you google fot it.

Today there is a Framework which can be used for drag and drop. It was introduced with Android 4.

You can find a nice tutorial at Google developer page:
https://developer.android.com/guide/topics/ui/drag-drop.html

Upvotes: 2

android developer
android developer

Reputation: 116040

try out my solution, which doesn't re-create layutParams and also handles the edges nicely:

https://stackoverflow.com/a/18806475/878126

Upvotes: 0

Thanks2Play
Thanks2Play

Reputation: 101

I know this question is a little old, but I found it when trying to implement drag and drop for a button. Using FoamyGuy's method I was able to get drag and drop to work using a LinearLayout as the parent view by setting the margins of the view in the onTouch method.

dragBtn.setOnTouchListener(new View.OnTouchListener() {

        public boolean onTouch(View v, MotionEvent me) {
            if (me.getAction() == MotionEvent.ACTION_MOVE  ){
                 LayoutParams params = new LayoutParams(v.getWidth(),  v.getHeight());
                 //set the margins. Not sure why but multiplying the height by 1.5 seems to keep my finger centered on the button while it's moving
                 params.setMargins((int)me.getRawX() - v.getWidth()/2, (int)(me.getRawY() - v.getHeight()*1.5), (int)me.getRawX() - v.getWidth()/2, (int)(me.getRawY() - v.getHeight()*1.5));
                 v.setLayoutParams(params);
             }
             return true;
        }
    });

NOTE: This only works if the view that you are dragging is the last view in the hierarchy. Otherwise it moves all the other views in relation to the view that you are dragging.

Upvotes: 10

FoamyGuy
FoamyGuy

Reputation: 46856

I am working on something similar to this. Here is the OnTouchListener that I am using:

         myOnTouchListener = new OnTouchListener() {
         public boolean onTouch(View v, MotionEvent me){
             if (me.getAction() == MotionEvent.ACTION_DOWN){
                 oldXvalue = me.getX();
                 oldYvalue = me.getY();
                 Log.i(myTag, "Action Down " + oldXvalue + "," + oldYvalue);
             }else if (me.getAction() == MotionEvent.ACTION_MOVE  ){
                LayoutParams params = new LayoutParams(v.getWidth(), v.getHeight(),(int)(me.getRawX() - (v.getWidth() / 2)), (int)(me.getRawY() - (v.getHeight())));
                v.setLayoutParams(params);
             }
             return true;
         }
     };

v is the view that you are wanting to move, in your case it you'd replace v with your button. Also note that in order to get this to work I had to use an AbsoluteLayout as the parent view in my xml file. I know that it is deprecated but it seemed more logical to use that then a RelativeLayout and trying to set the margins dynamically to move the view around. The formula that I used for the new x and y positions tries to make it so that the view is centered on your finger while you are moving it. But its not quite perfect, depending on the size of the view it will still be a little off center from your finger.

Upvotes: 7

Related Questions