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?
Asked
Active
Viewed 4.3k times
17
-
Try this tutorial.... http://www.anddev.org/basic_drag_and_drop-t3095.html – Noman Dec 13 '11 at 10:08
-
If you use a `SurfaceView` you can try to follow my tutorial part. http://www.droidnova.com/playing-with-graphics-in-android-part-vi,209.html In this part, I introduce you on how you can add and change the position on the SurfaceView while moving the touch. The part after that is a short game that implements all learned stuff in a short game. I think that should help you and show you how to do this... – WarrenFaith Nov 23 '10 at 13:12
3 Answers
30
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);
}
}
}
}
}

WarrenFaith
- 57,492
- 25
- 134
- 150

SBK
- 1,585
- 2
- 16
- 19
-
They look like two different answers to me, @WarrenFaith. One has a thread to keep updating the display, and one waits for user actions. As long as each answer is complete, I don't see anything wrong with posting more than one. – Don Kirkby Jan 11 '13 at 06:04
-
13
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.

eshayne
- 915
- 9
- 15
0
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
}

Nikitiy
- 37
- 4