This question has already been answered:

Here I attach the full code of the program

public class MainActivity1 extends Activity { public static float touchX = 50,touchY= 50; private float korX = touchX, korY = touchY, initX=0, initY=0, XX = 0, YY = 0; static int width; static int heigth; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GraphicsView myview = new GraphicsView(this); setContentView(myview); display(); } public void display(){ width = getWindowManager().getDefaultDisplay().getWidth(); heigth = getWindowManager().getDefaultDisplay().getHeight(); return; } public class GraphicsView extends SurfaceView implements SurfaceHolder.Callback { private DrawThread drawThread; public GraphicsView(Context context) { super(context); getHolder().addCallback(this); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { drawThread = new DrawThread(getHolder(), getResources()); drawThread.setRunning(true); drawThread.start(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { boolean retry = true; drawThread.setRunning(false); while (retry) { try { drawThread.join(); retry = false; } catch (InterruptedException e) { } } } public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: korX = touchX; korY = touchY; if((event.getRawY()> heigth*0.827) && (event.getRawX() > width * 0.2291) && event.getRawX() < width *0.7701 ) { initX = event.getRawX(); initY = event.getRawY(); } return true; case MotionEvent.ACTION_MOVE: if((event.getRawY()> heigth*0.827) && (event.getRawX() > width * 0.2291) && event.getRawX() < width *0.7701 ){ touchX = (korX + (event.getRawX()- initX)); touchY = (korY + (event.getRawY() - initY)); } // getHolder().addCallback(this); return true; } return false; } } 

and the second thread, although it is no longer relevant

 public class DrawThread extends Thread { private boolean running = false; private SurfaceHolder surfaceHolder; private Matrix matrix; private long prevTime; public Bitmap bitmap; public DrawThread(SurfaceHolder surfaceHolder,Resources resources){ this.surfaceHolder = surfaceHolder; bitmap = BitmapFactory.decodeResource(resources, R.drawable.face_box); } public void setRunning(boolean running){ this.running = running; } @Override public void run(){ while (running){ Canvas canvas = null; try { canvas = surfaceHolder.lockCanvas(null); if (canvas == null) continue; synchronized (surfaceHolder) { canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); onDraw(canvas); } } finally { if (canvas != null){ surfaceHolder.unlockCanvasAndPost(canvas); } } } } protected void onDraw(Canvas canvas) { canvas.drawBitmap(bitmap, MainActivity1.touchX, MainActivity1.touchY, null); } } 

The easiest way, of course, is if you run it in your computer and see all the jambs of the algorithm yourself in the emulator. I repeat, based on the variables used here. in the condition in ACTION_MOVE: and in general, the algorithm does not take into account the case when the finger continuously goes out of the area bounded by the coordinates and again goes in as inseparably there. It turns out that initX (the touch point to the screen from which the difference between this point and the current coordinate is considered) does not change. And it is required that when entering the area bounded by coordinates, the first coordinate becomes this initX, and the next ones will already consider the distance by which the icon itself is to be displaced relative to it. In general, either I don’t think how to write the correct algorithm, either I need to add some methods or use the control system interface ..

Reported as a duplicate by pavlofff , aleksandr barakin , zRrr , Grundy , Nick Volynkin ♦ Jul 12 '16 at 7:13 .

A similar question was asked earlier and an answer has already been received. If the answers provided are not exhaustive, please ask a new question .

  • These are not life-cycle methods, but events - they work when a tapa, scroll, long tapa, and swipe are detected (there is no sequence of actions in them, but only a response to the user's reaction) - pavlofff
  • Well, please tell me what all these parameters are onFling (MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) and in other events of the Gesture interface, which means each of the parameters. Can I use any of these events together with Action_Move so that it returns to me two coordinates, the last one and the current one when the finger is continuously guided across the screen. - Turalllb pm

2 answers 2

Use: MotionEvent.ACTION_DOWN press and MotionEvent.ACTION_UP release

  • I do not understand what it will give me. I press a finger, then I lead them around the screen, but I don’t let go, I don’t lift a finger and I don’t have a reason to set up to handle this event. I need a handler that, in an event at which I continuously move my finger, returns the past and current coordinates to me. MotionEvent.ACTION_MOVE returns only the current, MotionEvent.ACTION_DOWN as well as the current coordinate. - Turalllb 4:26 pm
  • Well, let's try this: 'public MotionEvent MyOldEvent;' and inside events assign / analyze this variable - santavital
  • Mmm MyoldEvent .. so I have not seen anywhere else .. how will I access the computer, I will start analyzing - Turalllb
  • And another question, is it possible if I keep my finger on the screen, without lifting it, to put a condition under which, if the finger is out of a range of certain coordinates, the action_move event and generally the entire onTouch method stopped working and resumed work again when the finger returns to these coordinates, resumed work so that the first coordinate in this area is treated as action_down and further as action_move? I tried to prescribe any breaks, but it does not come out - Turalllb
  • one
    Uraaaa, it turned out all the same you do not need any controllers and other methods to use. just by chance, the idea of ​​a correct algorithm came up with a fresh mind - Turalllb pm
 public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: korX = touchX; korY = touchY; initX = event.getRawX(); initY = event.getRawY(); return true; case MotionEvent.ACTION_MOVE: if((event.getRawY()> heigth*0.827) && (event.getRawX() > width * 0.2291) && event.getRawX() < width *0.7701 ){ if (flag) { korX = touchX; korY = touchY; initX = event.getRawX(); initY = event.getRawY(); flag = false; } else { touchX = (korX + (event.getRawX() - initX)); touchY = (korY + (event.getRawY() - initY)); } } else { flag = true; } return true; } return false; } 

initially flag = true Thanks to those who explained and answered my wrong questions)