user569873
user569873

Reputation: 424

Drag an drop a button on android .. help

i'm trying to drag and drop a button the problem is that when i use getX() at motion event it works but the button starts to tremble . When i call the method getRawX() it does not tremble but it jumps at least 80px right before i start the drag and drop .

how can i managed that , i'll post my code here:

    public class MyButton extends Button {

private final static int START_DRAGGING = 0;
private final static int STOP_DRAGGING = 1;

private int status;
private LinearLayout parentLayout;

public MyButton(Context context) {
    super(context);

}

public MyButton(Context context, AttributeSet attrs) {
    super(context, attrs);

}

public MyButton(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

}

@Override
public boolean onTouchEvent(MotionEvent event) {


    // Log.i("teste", "Button width: " + btWidth + ", Height : "+ btHeight);

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        status = START_DRAGGING;
        Log.i("teste", "Coordenada on ACTION_DOWN: " + (int) event.getRawX());
        break;
    case MotionEvent.ACTION_UP:
        status = STOP_DRAGGING;
        Log.i("teste", "Coordenada on ACTION_UP: " + (int) event.getRawX());
        break;
    case MotionEvent.ACTION_MOVE:
        if(status == START_DRAGGING){
            parentLayout.setPadding((int)event.getRawX(), 0,0,0);
            parentLayout.invalidate();
            Log.i("teste", "Coordenada on ACTION_MOVE: " + (int) event.getRawX());
        }                           
        break;

    }

    return true;
}

}

Upvotes: 1

Views: 4155

Answers (2)

Bill Lahti
Bill Lahti

Reputation: 476

I have been working on touching and moving objects too. I started out making something move in a similar way: changing the top and left padding. Pretty quickly, as I added more moveable objects to the screen, things got a bit confusing. I would touch one spot on the screen and something else would start moving. What was going on was there were multiple overlapping views on the screen. Only the top view would receive the touch events.

I found a post that suggested taking a look at the Android Launcher code and seeing how they did drag and drop. I think their approach is really good. You do have to add a ViewGroup to hold your moveable objects, but that works out. The bounds of views match what you see on the screen and you end up with no surprises. Events go to the view you expect.

If it turns out you are going to have more than one moveable object, you might want to take a look at my blog post: "Moving Views In Android". More explanations about the Android Launcher and source code are there.

Upvotes: 2

bigstones
bigstones

Reputation: 15267

event.getX() returns touch coordinates relative to your view (the button), event.getRawX() returns touch coordinates relative to the display, so I would think the first way is the correct one, if you set the padding of the button, instead of the layout. But you'll still have the "jump" problem because you're supposed to touch the button, not its edge, and the first move will put the edge under your finger.

I would try using a GestureDetector, its OnGestureListener has an onScroll() method that gives you the scrolling distance (it does the job of remembering last position and giving a relative motion), so that you can add that value to the padding, that is, you drag 10px => you add 10px of padding.

code example:

private GestureDetector gd =
            new GestureDetector(getContext(), new SimpleOnGestureListener() {
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2,
                                            float distanceX, float distanceY) {
        setPadding((int)(getPaddingLeft()+distanceX),0,0,0);
    }
    @Override
    public boolean onDown(MotionEvent e) {
        return true; // else no event will be handled
    }

I would also add some checks to prevent negative or excessive paddings.

Upvotes: 3

Related Questions