Pergunta

Hello
I've set up an onTouchListener within my application for an ImageView, my aim was to have an ImageView that the user would be able to drag around and place where ever they want within the app.

I've written some code using sample code found on the web for an onTouchListener that I thought would work but I'm having some problems with it, rather than allowing me to drag the image around, the image resizes and gets bigger or smaller when you drag your finger over it.

Does anyone have any ideas why?
Here's my code:

    ImageView t1img;

    t1img = (ImageView) findViewById(R.id.imgT1);

    windowWidth = getWindowManager().getDefaultDisplay().getWidth();
    windowHeight = getWindowManager().getDefaultDisplay().getHeight();

    t1img.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {

            layoutParams = (LayoutParams) t1img.getLayoutParams();

            switch (event.getAction()) {

                case MotionEvent.ACTION_DOWN:

                break;

                case MotionEvent.ACTION_MOVE:

                    int xCoord = (int) event.getRawX();
                    int yCoord = (int) event.getRawY();

                    if (xCoord > windowWidth) {

                        xCoord = windowWidth;
                    }

                    if (yCoord > windowHeight) {

                        yCoord = windowHeight;
                    }

                    layoutParams.leftMargin = xCoord - 25;
                    layoutParams.topMargin = yCoord - 75;

                    t1img.setLayoutParams(layoutParams);

                break;

                default:

                break;
            }

            return true;
        }
    });
Foi útil?

Solução

If you need to support gingerbread you can take a look at my example here

https://github.com/NAYOSO/android-dragview

if you only need to support jelly bean above you can use the Drag and Drop from android library you can see it from this article

http://developer.android.com/guide/topics/ui/drag-drop.html

For some explanation about the Drag and Drop view at first you need t create the touch listener and then call startDrag to start draging. As simple as that.

private final class dragTouchListener implements OnTouchListener {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);
                v.startDrag(data, shadowBuilder, v, 0);
                return true;
            } else {
                return false;
            }
        }

    }

To monitor the target of dropping place you can use onDragListener

private class dropListener implements OnDragListener {

    View draggedView;
    CustomTextView dropped;

    @Override
    public boolean onDrag(View v, DragEvent event) {
        switch (event.getAction()) {
        case DragEvent.ACTION_DRAG_STARTED:
            draggedView = (View) event.getLocalState();
            dropped = (CustomTextView) draggedView;
            draggedView.setVisibility(View.INVISIBLE);
            break;
        case DragEvent.ACTION_DRAG_ENTERED:
            break;
        case DragEvent.ACTION_DRAG_EXITED:
            break;
        case DragEvent.ACTION_DROP:

            CustomTextView dropTarget = (CustomTextView) v;
            dropTarget.setText(dropped.getText().toString());
            break;
        case DragEvent.ACTION_DRAG_ENDED:
            break;
        default:
            break;
        }
        return true;
    }

}

As you can see from my code there is many event but the main one is when the view is start being dragged, dropped and ended.

Don't forget to set the listener to view

    tvDrag.setOnTouchListener(new dragTouchListener());
    tvDrop.setOnDragListener(new dropListener())

I hope my explanation is clear enough! If you have further question I will try to answer it tonight or tomorrow :)

Outras dicas

I have done an example using thread. You can try this example for a smooth drag and drop bitmap image using touch Event listener

Download Demo or Code

I have created three classes MainActivity.Java Instatiates our BallView class and Adds setContentView to the BallView Class as shown below

package com.whatsonline.dragobject;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;

public class MainActivity extends Activity {

    private Bitmap bitmap;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        int w=getWindowManager().getDefaultDisplay().getWidth()-25;
        int h=getWindowManager().getDefaultDisplay().getHeight()-25;
        bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.p1);
        BallView ballView=new BallView(this, bitmap, w, h);
        setContentView(ballView);
    }

}

Our BallView extends the surfaceView class and implements the surface holder as shown below. Also, contains the draw method to draw the canvas and touchEvent listener to get the position of the Bitmap image to be moved and move along the drawn image Bitmap path.

package com.whatsonline.dragobject;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;


public class BallView extends SurfaceView implements SurfaceHolder.Callback {

    private Bitmap bitmap;
    private MyThread thread;
    private int x=25,y=25;
    int width,height;

    public BallView(Context context, Bitmap bmp, int w,int h) {
        super(context);

        width=w;
        height=h;
        bitmap=bmp;
        thread=new MyThread(getHolder(),this);
        getHolder().addCallback(this);
        setFocusable(true);
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);

       // bitmap = BitmapFactory.decodeResource(getResources(), bmp);
        canvas.drawColor(Color.BLUE);//To make background
        canvas.drawBitmap(bitmap, x-(bitmap.getWidth()/2),y-(bitmap.getHeight()/2), null);


    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        x=(int)event.getX();
        y=(int)event.getY();

        if(x<25)
            x=25;
        if(x> width)
            x=width;
        if(y <25)
            y=25;
        if(y > height)
            y=height;

        return true;
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
        // TODO Auto-generated method stub

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        thread.startrun(true);
        thread.start();

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {


        thread.startrun(false);
        thread.stop();

    }
}

and finally MainThread class call the onDraw method if it is running as shown below

package com.whatsonline.dragobject;

import android.graphics.Canvas;
import android.view.SurfaceHolder;

public class MyThread extends Thread {

    private SurfaceHolder msurfaceHolder;
    private BallView mballView;
    private boolean mrun =false;

    public MyThread(SurfaceHolder holder, BallView ballView) {

        msurfaceHolder = holder;
        mballView=ballView;
    }

    public void startrun(boolean run) {

        mrun=run;
    }

    @Override
    public void run() {

        super.run();
        Canvas canvas;
        while (mrun) {
            canvas=null;
            try {
                canvas = msurfaceHolder.lockCanvas(null);
                synchronized (msurfaceHolder) {
                    mballView.onDraw(canvas);
                }
            } finally {
                if (canvas != null) {
                    msurfaceHolder.unlockCanvasAndPost(canvas);
                }
            }
        }
    }

}

Download code here

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top