Android custom horizontal drag tremble

180 views Asked by At

I created a class that should be used to allow user to horizontally relocate a view by sliding his finger on a bar, the code is this

public class Dragger implements View.OnTouchListener {
  private View toDrag;
  private Point startDragPoint;
  private int offset;
  public Dragger (View bar, View toDragg){
    toDrag = toDragg;
    dragging = false;
    bar.setOnTouchListener(this);
  }
  public boolean onTouch(View v, MotionEvent evt) {
    switch (evt.getAction()) {
        case MotionEvent.ACTION_DOWN:
          startDragPoint = new Point((int) evt.getX(), (int) evt.getY());
          offset = startDragPoint.x - (int) toDrag.getX();
        break;
        case MotionEvent.ACTION_MOVE:
          int currentX = (int)evt.getX();
          Log.d("LOG","currentX=" + currentX);
          toDrag.setX(currentX-offset);
        break;
        case MotionEvent.ACTION_UP:
            int difference = (startDragPoint.x-offset)-(int)toDrag.getX();
            if(difference<-125){
              ((ViewManager) toDrag.getParent()).removeView(toDrag);
            }else{
                toDrag.setX(startDragPoint.x-offset);
            }
            dragging = false;
    }
    return true;
  }
}

In the oncreate of the main activity i just use it by calling his constructor like this:

new Dragger(barItem,itemToDrag);

It apparently work, but it seems to tremble a lot while dragging... I tried to understand why does it work so strangely, so i added a Log instruction in the ACTION_MOVE, and the result is that... even if i only move to right pixel by pixel sometimes the currentX instead of increasing by 1 it decrease of a variable number, sometimes 10, sometimes 18 and when i go to the next pixel it turn back to normal by increasing of 1... That really doesen't make sense... Some ideas on how to fix it?

1

There are 1 answers

4
cjds On BEST ANSWER

First guess: There are other fingers on the device which causes move to work erratically

Second guess: Right now you seem to be using the setX method more like a moveX and specifying the increment by which the function moves. This might not be what it was designed for

Third Point: Sometimes the move function acts finicky. It is always run (as in whenever there is a pointer on the screen) and depends on the position of the finger. I would recommend changing the function to make it like a step

Suggestion Make the action move like a step function that takes one value

case MotionEvent.ACTION_MOVE:
      int currentX = (int)evt.getX();
      if(abs(currentX)>10)currentX=(int) currentX/5;
      toDrag.setX(currentX-offset);