android拖放ImageView onTouchListener

时间:2014-07-31 09:24:16

标签: android drag-and-drop imageview ontouchlistener motionevent

您好我已经在我的应用程序中为ImageView设置了一个onTouchListener,我的目标是拥有一个用户可以在应用程序中拖动并放置在任意位置的ImageView。

我已经使用Web上的示例代码编写了一些代码,用于我认为可行的onTouchListener,但我遇到了一些问题,而不是让我拖动它图像周围,当您将手指拖过图像时,图像会调整大小并变大或变小。

有没有人有任何想法?
这是我的代码:

    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;
        }
    });

2 个答案:

答案 0 :(得分:7)

如果你需要支持姜饼,你可以看看我的例子

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

如果您只需要支持上面的果冻豆,您可以使用Android库中的拖放,您可以从这篇文章中看到它

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

有关拖放视图的一些说明 首先,您需要创建触摸侦听器,然后调用startDrag开始拖动。就这么简单。

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;
            }
        }

    }

要监控放置目标,可以使用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;
    }

}

从我的代码中可以看到有很多事件,但主要的是当视图开始被拖动,删除和结束时。

不要忘记将听众设置为

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

我希望我的解释足够清楚! 如果您有进一步的问题,我会尽力在今晚或明天回答:)

答案 1 :(得分:1)

我使用线程做了一个例子。您可以尝试使用触摸事件侦听器

来平滑拖放位图图像

Download Demo or Code

我创建了三个班级 MainActivity.Java 设置我们的BallView类并将setContentView添加到BallView类,如下所示

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);
    }

}

我们的BallView扩展了surfaceView类并实现了表面支架,如下所示。此外,还包含绘制canvas和touchEvent侦听器的draw方法,以获取要移动的Bitmap图像的位置,并沿绘制的图像Bitmap路径移动。

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();

    }
}

最后 MainThread类  如果它正在运行,请调用onDraw方法,如下所示

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