Android Bitmap snap to grid

Does anyone know if there is an easy way to snap images to a grid while dragging a bitmap?

At the moment, I can touch the bitmap and smoothly move it around the screen. I want it to snap to an invisible grid while dragging and dropping.

+4
source share
2 answers

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.

+4
source
  private PointF touchDown; private int gridCellSize = 10; private OnTouchListener touchListener = new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub switch(event.getAction()) { case MotionEvent.ACTION_DOWN: { touchDown = new PointF(event.getRawX(), event.getRawY()); break; } case MotionEvent.ACTION_MOVE: { RelativeLayout.LayoutParams par = (RelativeLayout.LayoutParams) v.getLayoutParams(); float yDeff = ((event.getRawY() - touchDown.y) / gridCellSize ) * gridCellSize; float xDeff = ((event.getRawX() - touchDown.x) / gridCellSize ) * gridCellSize; if(Math.abs(xDeff) >= gridCellSize) { par.leftMargin += (int)(xDeff / gridCellSize) * gridCellSize; touchDown.x = event.getRawX() - (xDeff % gridCellSize); } if(Math.abs(yDeff) >= gridCellSize) { par.topMargin += (int)(yDeff / gridCellSize) * gridCellSize; touchDown.y = event.getRawY() - (yDeff % gridCellSize); } v.setLayoutParams(par); break; } default : { break; } } return true; } }; 
+4
source

Source: https://habr.com/ru/post/1397974/


All Articles