How to detect single touch as well as multi-touch in onTouchEvent()

后端 未结 7 1887
眼角桃花
眼角桃花 2020-12-29 11:19

I used the following code to detect the single finger touch and double finger touch. The code detects the double finger touch (when count==2).

I need t

相关标签:
7条回答
  • 2020-12-29 11:42

    You checked that ACTION_DOWN but at the same time you also need to check ACTION_POINTER_DOWN, which makes sense more clear. try it

     @Override
        public boolean onTouchEvent(MotionEvent event) {    
             scaleGestureDetector.onTouchEvent(event);
    
             int action = event.getAction();
    
             if( (action == MotionEvent.ACTION_DOWN) && (action != MotionEvent.ACTION_POINTER_DOWN))
                 // Single touch
            else if ( action == MotionEvent.ACTION_POINTER_DOWN)
                //multi touch
    
            return true;
    }   
    

    Edited

    boolean multiTouch=false;
     @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
    
        int index= event.getActionIndex();
        int action = event.getAction();
    
        if( index ==1)
        {
            multiTouch=true;
            System.out.println("mutli");
        }
        else if (multiTouch==false)
            System.out.println("single");
        //else if (action== MotionEvent.ACTION_POINTER_1_UP)
        //  multiTouch=false;
        else if (action== MotionEvent.ACTION_MOVE && multiTouch)
            System.out.println("mutli");
        else if (action== MotionEvent.ACTION_MOVE && !multiTouch)
            System.out.println("single");
    
            return super.onTouchEvent(event);
    }
    

    EDITED:

     package com.pinch.detect;
    
    import java.io.BufferedInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLConnection;
    
    import android.app.Activity;
    import android.content.Context;
    import android.content.ContextWrapper;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.Bundle;
    import android.util.FloatMath;
    import android.util.Log;
    import android.view.Display;
    import android.view.MotionEvent;
    import android.view.ScaleGestureDetector;
    import android.view.View;
    import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener;
    import android.view.View.OnClickListener;
    import android.view.View.OnTouchListener;
    import android.widget.ImageView;
    import android.widget.TextView;
    import android.widget.Toast;
    
    public class PinchDetectorActivity extends Activity {
        TextView textGestureAction;
        ImageView img1, img2;
        static Bitmap bm, bm1;
    
    boolean multiTouch = false;
    Context context;
    float scaleFactor = 0.0f;
    float lastscale;
    int scr_width, scr_height;
    Display display;
    private ScaleGestureDetector scaleGestureDetector;
    
    /** Called when the activity is first created. */
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        textGestureAction = (TextView) findViewById(R.id.GestureAction);
        img1 = (ImageView) findViewById(R.id.img_left);
        img2 = (ImageView) findViewById(R.id.img_right);
        display = getWindowManager().getDefaultDisplay();
    
        scr_width = display.getWidth();
        scr_height = display.getHeight();
        Log.v("width >>", Integer.toString(scr_width));
        Log.v("height >>", Integer.toString(scr_height));
    
        bm = BitmapFactory.decodeResource(this.getResources(),
                R.drawable.fiction1);
        img1.setImageBitmap(bm);
        bm1 = BitmapFactory.decodeResource(this.getResources(),
                R.drawable.fiction2);
        img2.setImageBitmap(bm1);
        img1.setScaleType(ImageView.ScaleType.FIT_START);
        img2.setScaleType(ImageView.ScaleType.FIT_END);
    
        scaleGestureDetector = new ScaleGestureDetector(this,
                new MySimpleOnScaleGestureListener());
    
    
    
        img1.setOnTouchListener(new OnTouchListener(){
    
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // TODO Auto-generated method stub
                system.out.println("Image 1 touched");
                return false;
            }
    
        });
    
    
    
    img2.setOnTouchListener(new OnTouchListener(){
    
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // TODO Auto-generated method stub
                system.out.println("Image 2 touched");
                return false;
            }
    
        });
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
    
        scaleGestureDetector.onTouchEvent(event);
        int index = event.getActionIndex();
        Log.v("Index value ",index+"");
        int action = event.getAction();
    
        if (index == 1) {
            multiTouch = true;
            System.out.println("mutli1");
        } else if (multiTouch == false) {
            System.out.println("single1");
            img1.onTouch(view, event);
    
        }
    
         else if (action == MotionEvent.ACTION_MOVE && multiTouch) {
            System.out.println("mutli2");
             img2.onTouch(view, event);
    
            if (scaleFactor > 1) {
    
                Bitmap resizedbitmap = Bitmap.createScaledBitmap(bm,
                        scr_width / 2, scr_height, true);
                img1.setImageBitmap(resizedbitmap);
                Bitmap resizedbitmap1 = Bitmap.createScaledBitmap(bm1,
                        scr_width / 2, scr_height, true);
                img2.setImageBitmap(resizedbitmap1);
                Log.v("width >>", Integer.toString(scr_width));
                Log.v("height >>", Integer.toString(scr_height));
    
            } else if(scaleFactor<1){
    
                Log.v("width >>", Integer.toString(scr_width));
                Log.v("height >>", Integer.toString(scr_height));
                if (scr_width >= 640) {
                    Bitmap resizedbitmap = Bitmap.createScaledBitmap(bm,
                            scr_height + 90, scr_height, true);
    
                    img1.setImageBitmap(resizedbitmap);
    
                    Bitmap resizedbitmap1 = Bitmap.createScaledBitmap(bm1,
                            scr_height + 90, scr_height, true);
    
                    img2.setImageBitmap(resizedbitmap1);
                } else {
                    Bitmap resizedbitmap = Bitmap.createScaledBitmap(bm,
                            scr_height, scr_height + 30, true);
    
                    img1.setImageBitmap(resizedbitmap);
    
                    Bitmap resizedbitmap1 = Bitmap.createScaledBitmap(bm1,
                            scr_height, scr_height + 30, true);
    
                    img2.setImageBitmap(resizedbitmap1);
                }
    
            }
    
    
    
        } else if (action == MotionEvent.ACTION_MOVE && !multiTouch)
        {
            System.out.println("single2");
        }
    
        return super.onTouchEvent(event);
    
    }
    
    public class MySimpleOnScaleGestureListener extends
            SimpleOnScaleGestureListener {
    
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            // TODO Auto-generated method stub
    
            scaleFactor = detector.getScaleFactor();
    
            Log.v("scaleFactor >>>", scaleFactor + "");
    
            return true;
        }
    }
    
    }
    

    Latest:

    if (index == 1) {
            multiTouch = true;
            img2.onTouch(view, event);
        System.out.println("mutli1");
    } else if (multiTouch == false) {
        System.out.println("single1");
        img1.onTouch(view, event);
    
    }
    
     else if (action == MotionEvent.ACTION_MOVE && multiTouch) {
        System.out.println("mutli2");
    
    0 讨论(0)
  • 2020-12-29 11:51

    Have you tried using a OnDoubleTapListener ?

    Found this tutorial that can be helpful too showing how to detect a single tap and a double tap.

    0 讨论(0)
  • 2020-12-29 11:57

    Here is the code for detecting points and drawing each points in different color get compete example here

    public class custom_view extends View {
    
    
    
    private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    
    public int cu = 0;
    
    
    
    final int MAX_NUMBER_OF_POINT = 10;
    
    float[] x = new float[MAX_NUMBER_OF_POINT];
    
    float[] y = new float[MAX_NUMBER_OF_POINT];
    
    boolean[] touching = new boolean[MAX_NUMBER_OF_POINT];
    
    
    
    public custom_view(Context context, AttributeSet attrs, int defStyle) {
    
        super(context, attrs, defStyle);
    
        init();
    
    }
    
    public custom_view(Context context, AttributeSet attrs) {
    
        super(context, attrs);
    
        init();
    
    }
    
    
    
    public custom_view(Context context) {
    
        super(context);
    
        init();
    
    }
    
    void init() {
    
        paint.setStyle(Paint.Style.STROKE);
    
        paint.setStrokeWidth(40);
    
    }
    
    @Override
    
    protected void onDraw(Canvas canvas) {
    
        for (int i = 0; i < MAX_NUMBER_OF_POINT; i++) {
    
            if (touching[i]) {
    
                switch (i) {
    
                case 1:
    
                    paint.setColor(Color.BLUE);
    
                    break;
    
                case 2:
    
                    paint.setColor(Color.RED);
    
                    break;
    
                case 3:
    
                    paint.setColor(Color.CYAN);
    
                    break;
    
                case 4:
    
                    paint.setColor(Color.GREEN);
    
                    break;
    
                case 5:
    
                    paint.setColor(Color.YELLOW);
    
                    break;
    
                case 6:
    
                    paint.setColor(Color.MAGENTA);
    
                    break;
    
                case 7:
    
                    paint.setColor(Color.DKGRAY);
    
                    break;
    
                case 8:
    
                    paint.setColor(Color.LTGRAY);
    
                    break;
    
                case 9:
    
                    paint.setColor(Color.GREEN);
    
                    break;
    
                case 10:
    
                    paint.setColor(Color.BLACK);
    
    
    
                    break;
    
                    }
    
                canvas.drawCircle(x[i], y[i], 70f, paint);
    
            }
    
        }
    
    }
    
    @Override
    
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
        setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
    
                MeasureSpec.getSize(heightMeasureSpec));
    
    }
    
    @Override
    
    public boolean onTouchEvent(MotionEvent event) {
    
        int action = (event.getAction() & MotionEvent.ACTION_MASK);
    
        int pointCount = event.getPointerCount();
    
        for (int i = 0; i < pointCount; i++) {
    
            int id = event.getPointerId(i);
    
    
    
            if (id < MAX_NUMBER_OF_POINT) {
    
                x[id] = (int) event.getX(i);
    
                y[id] = (int) event.getY(i);
    
    
    
                if ((action == MotionEvent.ACTION_DOWN)
    
                        || (action == MotionEvent.ACTION_POINTER_DOWN)
    
                        || (action == MotionEvent.ACTION_MOVE)) {
    
                    touching[id] = true;
    
                } else {
    
                    touching[id] = false;
    
                    }
    
            }
    
        }
    
        invalidate();
    
        return true;
    
    }
    

    }

    0 讨论(0)
  • 2020-12-29 11:58

    I cannot reproduce count==2 for single touch. It is 1 for me for single touch. Try debug your code on real device and see what you actually have.

    Use event.getPointerId(i) along with event.getPointerCount() and see what these actual points of touch are.

    0 讨论(0)
  • 2020-12-29 12:00

    As the previous poster suggested, there are separate events for a single touch pointer up as opposed to action up. The sequence of motionEvents is as follows:

    1. ACTION_DOWN
    2. (ACTION_MOVE)
    3. ACTION_POINTER_DOWN
    4. (ACTION_MOVE)
    5. (ACTION_POINTER_ID_SHIFT)
    6. (repeat for as many fingers as come down)
    7. ACTION_POINTER_UP
    8. (repeat until only one finger remains)
    9. ACTION_UP

    Here's a good resource for understanding multitouch events, but the idea and easiest way to catch them all is to use a switch statement. I use this TouchImageView I found here. what it does is allows for scaling, and panning, and if you just click it, it performs the click, so you can add that processing code into an OnClickListener() or just insert it at line 125.

    0 讨论(0)
  • 2020-12-29 12:00

    You must need to user PointerID for MultiTouch. See this Complete Example

    private View.OnTouchListener OnTouchListener = new View.OnTouchListener() {
            public boolean onTouch(View view, MotionEvent event) { 
                int pointerIndex = ((event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT);
                int action = event.getAction() & MotionEvent.ACTION_MASK;
                int pointerId = event.getPointerId(pointerIndex);
                Log.i("", "Pointer ID = " + pointerId);
                switch (action) {
                case MotionEvent.ACTION_POINTER_UP: {
    
                    break;
                }
                }
                return true;
            }
        };
    
    0 讨论(0)
提交回复
热议问题