This is what I am doing in the application that I am finishing now. When the user drags something onto the screen, I show the visible snap grid, and the object snaps to that grid when the drag is completed. To show the grid, my approach is to use a separate custom View , which I called GridOverLayView . It overlays over the entire area of ββthe screen, and it very simply draws a snap grid in its onDraw() method. It becomes visible only when something stretches.
Now, regarding the actual Activity in which the drag and drop is performed, one specific constant that I defined:
static final int SNAP_GRID_INTERVAL = 20;
When an object moves, i.e. when handling event.getAction()==MotionEvent.ACTION_MOVE events in my OnTouchListener , I bind the location of the object to the grid using the following:
RelativeLayout.LayoutParams par = (RelativeLayout.LayoutParams) mThingBeingDragged.getLayoutParams(); par.topMargin = Math.round((event.getRawY() - draggedInitialY) / SNAP_GRID_INTERVAL ) * SNAP_GRID_INTERVAL; par.leftMargin = Math.round((event.getRawX() - draggedInitialX) / SNAP_GRID_INTERVAL ) * SNAP_GRID_INTERVAL; mThingBeingDragged.setLayoutParams(par);
... where draggedInitialY and draggedInitialX keep the initial touch position recorded during the initial MotionEvent.ACTION_DOWN .
Another nice touch is to allow you to move the object to move without snap, but snap it to the grid only in .ACTION_UP when the user lifts his finger. In practice, it is much more pleasant to use.
source share