Tag Archives: onTouch

Android solution to the conflict of calling ontouch and onclick at the same time

The order and association of the ontouch, onclick, onlongclick events of button:

1.ontouch returns false
first, the down event of the ontouch event occurs. At this time, if you press and hold for a long time, the onlongclick event will be triggered;
then, the up event of the ontouch event will occur. After the up, the onclick event will be triggered.

2. ontouch returns true
first, the down event of ontouch event occurs, and then the up event of ontouch event occurs; during this period, onclick and onlongclick events are not triggered

3. ontouch: down returns true, up returns false: the result is the same as the second.
Mechanism analysis:
in ontouch events, the return value of the down event marks whether the event is a click event (returns false, which is a click event; returns true, which is not recorded as a click event), while the up event marks the end time of the event, which is to judge whether it is a long press.
As long as down returns true, the system will not record this event as a click event, and the onclick or onlongclick event will not be triggered. Therefore, even if false is returned when up, the system will not continue to trigger the onclick event.

4. ontouch: down returns false, up returns true:
first, the down event of ontouch event occurs, at this time:
long press to trigger the onlongclick event, and then the up event of ontouch event occurs, over.
Short press to trigger the up event of ontouch first. After a certain time, the onlongclick event will be triggered automatically.
Mechanism analysis:
in ontouch events, the return value of the down event marks whether the event is a click event (returns false, which is a click event; returns true, which is not recorded as a click event), while the up event marks the end time of the event, which is to judge whether it is a long press.
When down returns false, the event is marked as a click event, while up returns true, it means that the event has not been finished, that is, it has been pressed for a long time. When the critical time of pressing for a long time is reached, the long press event will be triggered naturally, while the onclick event will not be triggered to 0

public class ImageZoomActivity extends Activity implements OnTouchListener {
   private static final String TAG = "Touch";
   // These matrices will be used to move and zoom image
   Matrix matrix = new Matrix();
   Matrix savedMatrix = new Matrix();

   // We can be in one of these 3 states
   static final int NONE = 0;
   static final int DRAG = 1;
   static final int ZOOM = 2;
   int mode = NONE;

   // Remember some things for zooming
   PointF start = new PointF();
   PointF mid = new PointF();
   float oldDist = 1f;
 private ImageView view;
 private boolean keyUpDown=false;
 private int timer=0;
 
   /* (non-Javadoc)
 * @see android.app.Activity#onCreate(android.os.Bundle)
 */
@Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      requestWindowFeature(Window.FEATURE_NO_TITLE);
      setContentView(R.layout.touch);
      view = (ImageView) findViewById(R.id.imageView);
      Intent intent=getIntent();
//      Drawable drawable=loadImgByFilePath(intent.getStringExtra("toZoom"));
      view.setImageURI(Uri.parse(intent.getStringExtra("toZoom")));
      view.setOnTouchListener(this);
   }

 private Handler clickHandler = new Handler(){
  @Override
  public void handleMessage(Message msg) {
   if(msg.what==0){
    keyUpDown=true;
    keyUpDownListener();
   }else if(msg.what==1){
    keyUpDown=false;
    if(timer<=1)
     ImageZoomActivity.this.finish();
    else timer=0;
   }
  }
 };
 private int keyUpDownListener() {
  new Thread(){
   public void run(){
    while(keyUpDown){
     try {
      sleep(200);
      timer++;
      Log.d("info","timing:timer="+timer);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
    }
   }
  }.start();
  return timer;
 }

   @Override
   public boolean onTouch(View v, MotionEvent event) {
      ImageView view = (ImageView) v;

      // Dump touch event to log
//      dumpEvent(event);

      // Handle touch events here...
      switch (event.getAction() & MotionEvent.ACTION_MASK) 
      {
      case MotionEvent.ACTION_DOWN:
         savedMatrix.set(matrix);
         start.set(event.getX(), event.getY());
         Log.d(TAG, "mode=DRAG");
        clickHandler.sendEmptyMessage(0);
         mode = DRAG;
         break;
      case MotionEvent.ACTION_POINTER_DOWN:
         oldDist = spacing(event);
         Log.d(TAG, "oldDist=" + oldDist);
         if (oldDist > 10f) {
            savedMatrix.set(matrix);
            midPoint(mid, event);
            mode = ZOOM;
            Log.d(TAG, "mode=ZOOM");
         }
         break;
      case MotionEvent.ACTION_UP:clickHandler.sendEmptyMessage(1);
      case MotionEvent.ACTION_POINTER_UP:
         mode = NONE;
         Log.d(TAG, "mode=NONE");
         break;
      case MotionEvent.ACTION_MOVE:
         if (mode == DRAG) {
            // ...
            matrix.set(savedMatrix);
            matrix.postTranslate(event.getX() - start.x,
                  event.getY() - start.y);
         }
         else if (mode == ZOOM) {
            float newDist = spacing(event);
            Log.d(TAG, "newDist=" + newDist);
            if (newDist > 10f) {
               matrix.set(savedMatrix);
               float scale = newDist/oldDist;
               matrix.postScale(scale, scale, mid.x, mid.y);
            }
         }
         break;
      }

      view.setImageMatrix(matrix);
      return true; // indicate event was handled
   }

   /** Determine the space between the first two fingers */
   private float spacing(MotionEvent event) {
      float x = event.getX(0) - event.getX(1);
      float y = event.getY(0) - event.getY(1);
      return FloatMath.sqrt(x * x + y * y);
   }

   /** Calculate the mid point of the first two fingers */ 
   private void midPoint(PointF point, MotionEvent event) { 
      float x = event.getX(0) + event.getX(1); 
      float y = event.getY(0) + event.getY(1); 
      point.set(x/2, y/2); 
   } 
}

PS: if ontouch returns true or false, you can try to return it

super.onTouchEvent(event)