Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Based on GreyBeardedGeek's tip about .getLocationOnScreen, here is a sample onTouchListener that moves a View with a finger. It successfully accommodates menus, toolbars, status bars, the parent View not being centered on either axis, etc. I thought I'd share this since I've seen so many posts on the topic but none that really completely answered the question. It is intentionally wordy, and uses more locals than is necessary, to help illustrate what is happening.</p> <pre><code>public boolean onTouch(View v,MotionEvent event) { boolean bExitValue = true; int iOffsetX; int iOffsetY; int iNewX; int iNewY; int[] aLocation = new int [ 2 ]; int iAction; iAction = event.getActionMasked(); if (MotionEvent.ACTION_MOVE == iAction) { v.getLocationOnScreen(aLocation); // get absolute physical location of this View iOffsetX = (aLocation [ 0 ] - (int) v.getX()); // subtract out this View's relative location within its parent View... iOffsetY = (aLocation [ 1 ] - (int) v.getY()); // ...yielding the offsets that convert getRawX/Y's coords to setX/Y's coords iNewX = (int) event.getRawX(); // get absolute physical coords of this touch iNewY = (int) event.getRawY(); iNewX -= iOffsetX; // remove parent View's screen offset (calc'd above) iNewY -= iOffsetY; iNewX -= iRelX; // remove stored touch offset iNewY -= iRelY; v.setX(iNewX); // finally, move View to new coords (relative to its parent View) v.setY(iNewY); } else if (MotionEvent.ACTION_DOWN == iAction) { iRelX = (int) event.getX(); // preserve offset of this touch within the View iRelY = (int) event.getY(); } else { bExitValue = false; } return(bExitValue); } </code></pre> <p>Key points:</p> <ul> <li><p>The touch's offset within the View must be captured and stored in your ACTION_DOWN handler to Class-level fields (i.e. static variables). You want to preserve this offset so the View maintains its positional relationship with the finger, but you can't just grab a fresh copy with every ACTION_MOVE because they will exactly offset the finger movement and no movement will occur.</p></li> <li><p>View.getLocationOnScreen returns absolute coordinates, whereas View.getX/Y returns coordinates relative to the parent View. This is how non-fullscreen parent Views are handled. The difference between these two coordinate pairs is the offset that converts MotionEvent.getRawX/Y's absolute coordinates to the parent-View-relative coordinates required by View.setX/Y.</p></li> </ul> <p>A big thanks to GreyBeardedGeek for identifying View.getLocationOnScreen. Hopefully this code excerpt will help someone else. Thanks!</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload