how to use correct dragging of a view on android

android developer picture android developer · Oct 25, 2011 · Viewed 12.7k times · Source

it seems that there are a lot of solutions of how to use dragging of views on android .

however, they are either too slow or buggy.

a known solution is to have a framelayout , and the view simply changes its layoutParams as it moves using the OnTouchListener ,as described here: http://www.anddev.org/novice-tutorials-f8/android-drag-and-drop-of-normal-views-not-bitmaps-t13404.html however, if the view is an imageView , when reaching the most right (or most bottom) side of the framelayout , the image shrinks .

another possible solution is to use the canvas in order to show the dragged content , as described here: http://www.anddev.org/basic_drag_and_drop-t3095.html however, i'm not sure how to use it for complex views.

does anyone know of a good solution , one that let the size of the dragged view stay the same , no matter where it is in its container?

please help me .

Answer

android developer picture android developer · Sep 14, 2013

Here's a complete solution for a simple imageView dragging:

findViewById(R.id.imageView).setOnTouchListener(new OnTouchListener()
  {
    int prevX,prevY;

    @Override
    public boolean onTouch(final View v,final MotionEvent event)
      {
      final FrameLayout.LayoutParams par=(FrameLayout.LayoutParams)v.getLayoutParams();
      switch(event.getAction())
        {
        case MotionEvent.ACTION_MOVE:
          {
          par.topMargin+=(int)event.getRawY()-prevY;
          prevY=(int)event.getRawY();
          par.leftMargin+=(int)event.getRawX()-prevX;
          prevX=(int)event.getRawX();
          v.setLayoutParams(par);
          return true;
          }
        case MotionEvent.ACTION_UP:
          {
          par.topMargin+=(int)event.getRawY()-prevY;
          par.leftMargin+=(int)event.getRawX()-prevX;
          v.setLayoutParams(par);
          return true;
          }
        case MotionEvent.ACTION_DOWN:
          {
          prevX=(int)event.getRawX();
          prevY=(int)event.getRawY();
          par.bottomMargin=-2*v.getHeight();
          par.rightMargin=-2*v.getWidth();
          v.setLayoutParams(par);
          return true;
          }
        }
      return false;
      }
  });