0

So I'm messing around with interacting with touch events/gestures in Android. One of the first things I did was make a textview in a relativelayout that I can drag around.

Java code is:

public class draggystuff extends ActionBarActivity implements View.OnTouchListener {

private TextView mTextView;
private ViewGroup mRootLayout;
private int _xDelta;
private int _yDelta;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_draggystuff);

    mRootLayout = (ViewGroup) findViewById(R.id.root);
    mTextView = (TextView) mRootLayout.findViewById(R.id.textView);

    RelativeLayout.LayoutParams layoutParams =  (RelativeLayout.LayoutParams) mTextView.getLayoutParams();

    mTextView.setOnTouchListener(this);
}

@Override
public boolean onTouch(View v, MotionEvent event) {
    final int X = (int) event.getRawX();
    final int Y = (int) event.getRawY();
    switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) mTextView.getLayoutParams();

            _xDelta = X - lParams.leftMargin;
            _yDelta = Y - lParams.topMargin;
            Log.d("x is", String.valueOf(_xDelta));
            Log.d("y is", String.valueOf(_yDelta));
            break;
        case MotionEvent.ACTION_UP:
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            break;
        case MotionEvent.ACTION_POINTER_UP:
            break;
        case MotionEvent.ACTION_MOVE:
            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mTextView
                    .getLayoutParams();
            layoutParams.leftMargin = X - _xDelta;
            layoutParams.topMargin = Y - _yDelta;
            layoutParams.rightMargin = -250;
            layoutParams.bottomMargin = -250;
            mTextView.setLayoutParams(layoutParams);
            break;
    }
    mRootLayout.invalidate();
    return true;
}
}

This works just fine. It sets up the textview in the upper left corner, and I can drag it around the screen. When I stop dragging, it stays put where I left it.

Next I decided that I should start with the textview in the center of the screen. To do this, I modified my OnCreate method as follows:

 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_draggystuff);

    mRootLayout = (ViewGroup) findViewById(R.id.root);
    mTextView = (TextView) mRootLayout.findViewById(R.id.textView);

    RelativeLayout.LayoutParams layoutParams =  (RelativeLayout.LayoutParams) mTextView.getLayoutParams();

    layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
    mTextView.setOnTouchListener(this);
}

This accomplished the goal of centering my TextView, but now it would not move when I dragged it. I figured this might be because the centering attribute was locking it in place. I thought that if I removed the centering attribute before I changed its coordinates, that might work. So I added a line to my ontouch method as follows:

public boolean onTouch(View v, MotionEvent event) {
    final int X = (int) event.getRawX();
    final int Y = (int) event.getRawY();
    switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) mTextView.getLayoutParams();

            _xDelta = X - lParams.leftMargin;
            _yDelta = Y - lParams.topMargin;
            Log.d("x is", String.valueOf(_xDelta));
            Log.d("y is", String.valueOf(_yDelta));
            break;
        case MotionEvent.ACTION_UP:
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            break;
        case MotionEvent.ACTION_POINTER_UP:
            break;
        case MotionEvent.ACTION_MOVE:
            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mTextView
                    .getLayoutParams();
            layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, 0);
            layoutParams.leftMargin = X - _xDelta;
            layoutParams.topMargin = Y - _yDelta;
            layoutParams.rightMargin = -250;
            layoutParams.bottomMargin = -250;
            mTextView.setLayoutParams(layoutParams);

            break;
    }
    mRootLayout.invalidate();
    return true;
}

Now however, the textview starts out in the middle of the screen, but as soon as a drag even begins, it instantly moves back to the upper left before following the relative movements of my finger!

How can I center the textview in the relativelayout in such a way that it neither locks in place nor moves back to the corner before dragging?

Sven
  • 55
  • 7

2 Answers2

0

Instead of using a relative layout, try a linear layout and use setGravity(Gravity.CENTER) on your textview to see whether it is indeed the addrule method that causes the textview to ignore any touch events.

Also, have you tried applying the layout params using XML, and seeing whether the problem is reproduced over there?

Last, does the textview move to the upper-left on the down action event or the move action event?

Samee24
  • 36
  • 2
  • adding the param using XML causes the same behavior. I can't actually tell really if it is happening on the down or the move event though, as I can't seem to get a tap to register as a down-up only. Apparenly I have a shaky thumb... I'll try it with the linearlayout – Sven Jun 03 '15 at 03:40
  • SO interesting things happened when I put it in a linear layout and used setGravity. The textview IS then draggable from the center of the screen. BUT the "freedom" of dragging is different along the x and y axes. The textview follows my finger perfectly on vertical drags. On horizontal drags though, it moves more slowly, relative to my finger, such that my finger moves farther than the textview. If I use Gravity.CENTER_VERTICAL, it is draggable on both axes. CENTER_HORIZONTAL, has the same drag freedom issue. – Sven Jun 03 '15 at 04:16
0

So to fix this issue I changed the way I Was moving the view.

My xdelta and ydelta variables became the following:

_xDelta = X - mTextView.getX();
_yDelta = Y - mTextView.getY();

Then in my action_move event, instead of setting the left and top margins, I simply used the setX and setY methods like so:

mTextView.setX(X-_xDelta);
mTextView.setY(Y-_yDelta);
Sven
  • 55
  • 7