Creating a copy/clone of imageview android

2019-05-16 09:53发布

问题:

I am creating a drag and drop application that drags an object on the main layout. My problem is I want to have unlimited/infinity copy of the image view so I can drag the image as many as I can.

For example the heart shape, when I already drag the image I cannot have another heart shape because I only have one image(heart) in the layout.

This is my code on touch on imageViews (Star, Heart, lightning):

private final class MyTouchListener implements OnTouchListener {

    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
          ClipData data = ClipData.newPlainText("", "");
          DragShadowBuilder shadowBuilder = new DragShadowBuilder(view);
          view.startDrag(data, shadowBuilder, view, 0);
          view.setVisibility(View.INVISIBLE);
          return true;
        } else {
        return false;
        }
      }

    }

this is my drag listener of the drop zone/main image:

class MyDragListener implements OnDragListener {
    @Override
      public boolean onDrag(View v, DragEvent event) {
        int action = event.getAction();
        final int X = (int) event.getX();
        final int Y = (int) event.getY();

        switch (event.getAction()) {
        case DragEvent.ACTION_DRAG_STARTED:
        // do nothing
          break;
        case DragEvent.ACTION_DRAG_ENTERED:
          break;
        case DragEvent.ACTION_DRAG_EXITED:        
          break;
        case DragEvent.ACTION_DROP:
          // Dropped, reassign View to ViewGroup
          View view = (View) event.getLocalState();
          ViewGroup owner = (ViewGroup) view.getParent();
          owner.removeView(view);
          RelativeLayout container = (RelativeLayout) v;

          RelativeLayout.LayoutParams params1 = new RelativeLayout.LayoutParams(30, 30);
           params1.leftMargin = (int) event.getX() - 15;
           params1.topMargin = (int) event.getY() -15;

          container.addView(view,params1);
          view.setVisibility(View.VISIBLE);
          break;
        case DragEvent.ACTION_DRAG_ENDED:
          default:
          break;
        }
        return true;
      }
  }

回答1:

Drag and drop in your case is much easier to develop with canvas.

Create a class that extends View, make a rect to draw you image inside, setOntouch on that view, let rect follow your touch, and use invalidate() to force redraw the view.

Edit When using canvas you don't get headache from margins and layout parameters, it's just straightforward.

DragDropView.java

public class DragDropView extends View implements OnTouchListener  {
    Rect originalRect , draggableRect;
    int left, right, top, bottom, newX, newY, size;
    Drawable originalDrawable,draggableDrawable;

    public DragDropView(Context context)
    {
        super(context, null);
        size = 20;
        originalRect= new Rect();
        originalRect.set(200, 200, 240, 240); //left , top , right , bottom
        draggableRect= new Rect();
        draggableRect.set(200, 200, 240, 240);
        originalDrawable = getResources().getDrawable(R.drawable.ic_launcher);
        draggableDrawable = getResources().getDrawable(R.drawable.ic_launcher);
        originalDrawable.setBounds(originalRect); // since it wont move no need to do that in onDraw()
        newX = 220;
        newY=220;
        this.setOnTouchListener(this);
    }
    public DragDropView(Context context, AttributeSet attrs)
    {    super(context, attrs);    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
        originalDrawable.draw(canvas);
        draggableRect.set(newX-size, newY-size, newX+size, newY+size);
        draggableDrawable.setBounds(draggableRect);
        draggableDrawable.draw(canvas);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event)
    {
        newX = (int)event.getX();
        newY = (int)event.getY();
        invalidate(); // force redraw

        //if you need special touch events
//      //on touch down
//      if( event.getAction() == MotionEvent.ACTION_DOWN )
//      {   }
//      //on touch move
//      if( event.getAction() == MotionEvent.ACTION_MOVE )
//      {   }
//      //on touch up
//      if( event.getAction() == MotionEvent.ACTION_UP )
//      {   }

        return true; // always return true to let touch listener listen to next touch
    }
}

YourActivity.java

DragDropView dragDropView = new DragDropView();