在 Android 中触摸并拖动图像

发布于 2024-10-04 03:12:56 字数 55 浏览 0 评论 0原文

我正在研究一些示例,其中我想拖动与 Android 中的触摸相对应的图像。有人知道我该怎么做吗?

I am working on some example in which i want to drag the image corresponding to touch in Android. Does anybody have an idea about how I can do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

迷爱 2024-10-11 03:12:56
public class TouchBall extends Activity {


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    int w=getWindowManager().getDefaultDisplay().getWidth()-25;
    int h=getWindowManager().getDefaultDisplay().getHeight()-25;

    BallView ballView=new BallView(this,w,h);
    setContentView(ballView);
}


}
public class BallView extends SurfaceView implements SurfaceHolder.Callback {

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

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

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

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

        bitmap =BitmapFactory.decodeResource(getResources(), R.drawable.ball_green);
        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 > 405)
                y=405;      
        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();

    }   
 }

线:

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

}
public class TouchBall extends Activity {


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    int w=getWindowManager().getDefaultDisplay().getWidth()-25;
    int h=getWindowManager().getDefaultDisplay().getHeight()-25;

    BallView ballView=new BallView(this,w,h);
    setContentView(ballView);
}


}
public class BallView extends SurfaceView implements SurfaceHolder.Callback {

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

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

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

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

        bitmap =BitmapFactory.decodeResource(getResources(), R.drawable.ball_green);
        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 > 405)
                y=405;      
        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();

    }   
 }

thread:

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

}
篱下浅笙歌 2024-10-11 03:12:56

作为对 TouchBall 答案的轻微修改 - 如果您确实没有游戏循环 - 换句话说,屏幕的唯一变化直接归因于用户输入 - 那么省略线程可能更有意义。否则,即使没有任何变化,它也会不断循环和重绘。所以:

public class TouchBall extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        int w=getWindowManager().getDefaultDisplay().getWidth()-25;
        int h=getWindowManager().getDefaultDisplay().getHeight()-25;

        BallView ballView=new BallView(this,w,h);
        setContentView(ballView);
    }
}

public class BallView extends SurfaceView implements SurfaceHolder.Callback {
    private Bitmap bitmap ;
    private int x=20,y=20;int width,height;

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

        width=w;
        height=h;
        getHolder().addCallback(this);
        setFocusable(true);
    }

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

        bitmap =BitmapFactory.decodeResource(getResources(), R.drawable.ball_green);
        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 > 405)
            y=405;

        updateBall();

        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) {
        // TODO Auto-generated method stub
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub
    }

    private void updateBall() {
        Canvas canvas = null;
        try {
            canvas = getHolder().lockCanvas(null);
            synchronized (getHolder()) {
                this.onDraw(canvas);
            }
        }
        finally {
            if (canvas != null) {
                getHolder().unlockCanvasAndPost(canvas);
            }
        }
    }   
}

诚然,我是 Android 开发的新手,所以我可能在这里遗漏了一些东西。

As a slight modification to the TouchBall answer - if you really don't have a game loop - in other words, the only changes to the screen are directly due to user input - then it might make more sense to leave out the thread. Otherwise it is just constantly looping and redrawing even if nothing has changed. So:

public class TouchBall extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        int w=getWindowManager().getDefaultDisplay().getWidth()-25;
        int h=getWindowManager().getDefaultDisplay().getHeight()-25;

        BallView ballView=new BallView(this,w,h);
        setContentView(ballView);
    }
}

public class BallView extends SurfaceView implements SurfaceHolder.Callback {
    private Bitmap bitmap ;
    private int x=20,y=20;int width,height;

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

        width=w;
        height=h;
        getHolder().addCallback(this);
        setFocusable(true);
    }

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

        bitmap =BitmapFactory.decodeResource(getResources(), R.drawable.ball_green);
        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 > 405)
            y=405;

        updateBall();

        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) {
        // TODO Auto-generated method stub
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub
    }

    private void updateBall() {
        Canvas canvas = null;
        try {
            canvas = getHolder().lockCanvas(null);
            synchronized (getHolder()) {
                this.onDraw(canvas);
            }
        }
        finally {
            if (canvas != null) {
                getHolder().unlockCanvasAndPost(canvas);
            }
        }
    }   
}

Admittedly, I am new to Android development, so I may be missing something here.

漫漫岁月 2024-10-11 03:12:56

Kotlin 中安静简单的解决方案。不检查 ImageView 是否移出其父视图甚至整个屏幕。此代码必须放置在扩展 AppCompatImageView 的类中

    private var xStart = 0
    private var yStart = 0
    private var leftStart = 0
    private var topStart = 0
    private var isDragging = false

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(event: MotionEvent?): Boolean {
        requireNotNull(event)
        when(event.action) {
            MotionEvent.ACTION_DOWN -> {
                xStart = event.rawX.toInt()
                yStart = event.rawY.toInt()
                topStart = top
                leftStart = left
                isDragging = true
            }
            MotionEvent.ACTION_MOVE -> {
                if(isDragging) {
                    val deltaX = event.rawX.toInt() - xStart
                    val deltaY = event.rawY.toInt() - yStart

                    left = leftStart + deltaX
                    top = topStart + deltaY
                }
            }
            MotionEvent.ACTION_UP -> {
                isDragging = false
            }
        }
        return true
    }

Quiet simple solution in Kotlin. Does not check if the ImageView is moving outta its parent view or even the whole screen. This code must be placed inside a class that extends AppCompatImageView

    private var xStart = 0
    private var yStart = 0
    private var leftStart = 0
    private var topStart = 0
    private var isDragging = false

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(event: MotionEvent?): Boolean {
        requireNotNull(event)
        when(event.action) {
            MotionEvent.ACTION_DOWN -> {
                xStart = event.rawX.toInt()
                yStart = event.rawY.toInt()
                topStart = top
                leftStart = left
                isDragging = true
            }
            MotionEvent.ACTION_MOVE -> {
                if(isDragging) {
                    val deltaX = event.rawX.toInt() - xStart
                    val deltaY = event.rawY.toInt() - yStart

                    left = leftStart + deltaX
                    top = topStart + deltaY
                }
            }
            MotionEvent.ACTION_UP -> {
                isDragging = false
            }
        }
        return true
    }
夏见 2024-10-11 03:12:56

以下是 ConstraintLayout 的示例:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/objecttodrag"
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:src="@drawable/image"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintVertical_bias="0.5"/>
</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.java

package com.kevin.dragdrop;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import android.os.Bundle;
import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {   
    ImageView imageView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView) findViewById(R.id.objecttodrag);}
    float x, y;
    float dx, dy;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            x = event.getX();
            y = event.getY();}
        if (event.getAction() == MotionEvent.ACTION_MOVE) {
            dx = event.getX() - x;
            dy = event.getY() - y;
            imageView.setX(imageView.getX() + dx);
            imageView.setY(imageView.getY() + dy);
            x = event.getX();
            y = event.getY();}
        return super.onTouchEvent(event);
    } }

鸣谢:

特别感谢 'chandan k”。

Here is an example for ConstraintLayout:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/objecttodrag"
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:src="@drawable/image"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintVertical_bias="0.5"/>
</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.java

package com.kevin.dragdrop;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import android.os.Bundle;
import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {   
    ImageView imageView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView) findViewById(R.id.objecttodrag);}
    float x, y;
    float dx, dy;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            x = event.getX();
            y = event.getY();}
        if (event.getAction() == MotionEvent.ACTION_MOVE) {
            dx = event.getX() - x;
            dy = event.getY() - y;
            imageView.setX(imageView.getX() + dx);
            imageView.setY(imageView.getY() + dy);
            x = event.getX();
            y = event.getY();}
        return super.onTouchEvent(event);
    } }

Credits:

Special thanks to 'chandan k' for the code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文