我正在做一些示例,希望能够实现在安卓设备上触摸并拖动图像的功能。有人知道如何实现吗?
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);
}
}
}
}
}
对于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);
}
}
}
}
诚然,我对安卓开发还很陌生,所以可能在这方面有所遗漏。
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
}
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' 提供的代码。
SurfaceView
,可以尝试按照我的教程部分进行操作。http://www.droidnova.com/playing-with-graphics-in-android-part-vi,209.html 在这一部分中,我将向您介绍如何在移动触摸时添加和更改SurfaceView上的位置。之后的部分是一个短小的游戏,它实现了所有学到的东西。我认为这应该会帮助您并向您展示如何做到这一点... - WarrenFaith