ClassA
ClassA

Reputation: 2660

Elapsed time between first and second ACTION_DOWN

- The main this I want to accomplish with this question is to distinguish between single and double tap, I want to perform actions depending on single/double tap

I'm trying to get the elapsed time between the first and next MotionEvent.ACTION_DOWN. I have seen this question where he asked how to get the elapsed time between MotionEvent.ACTION_DOWN and MotionEvent.ACTION_UP using System.nanoTime(); My question is not the same...

Android Image viewer has this function, when you double tab - it zooms in. When you single tap - it hides the tools. I think this is done by measuring the time between the first and next ACTION_DOWN

Here is what I currently have:

ImageView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){
            if(!gone){
                hide.setVisibility(View.GONE);
                gone = true;
            }else{
                hide.setVisibility(View.VISIBLE);
                gone = false;
            }
        }
        return true;
    }
});

The above code will hide the view on every second tap, no matter the elapsed time.

I'm looking for a way to measure the elapsed time between the first MotionEvent.ACTION_DOWN and the next MotionEvent.ACTION_DOWN, any ideas?


Research I have done:

AND COUNTLESS STACKOVERFLOW QUESTIONS.

I still could not find what I was looking for.


EDIT 1:

Ok so I'm using this library to handle the zoom of the image view, but this library doesn't support single tab (I could not find docs saying it can). Now I'm trying to figure out a work around for this by detecting a single tap. this is what I have now:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ImageHolder = (PhotoView) findViewById(R.id.ImageHolder);
    ImageHolder.setImageURI(myUri);

    ImageHolder.setOnTouchListener(new View.OnTouchListener() {
        long lastDown = 0;
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){
                long now = System.currentTimeMillis();
                if(now - lastDown < 500) {// the second touch was 500ms less ago
                    Toast.makeText(getApplicationContext(), "Double Tap", Toast.LENGTH_LONG).show();

                }

                    lastDown = now;

            }
            return true;
        }
    });

This works fine for detecting the time between first and next ACTION_DOWN, but it overrides the functions of the library so the double tap to zoom doesn't work when implementing this.


EDIT 2:

I have found this that includes the following gesture class, it is to big to post so please have a look HERE.

In the info the guy say to use the following to detect a single tap:

img.setOnTouchImageViewListener(new TouchImageView.OnTouchImageViewListener() {

        @Override
        public void onMove() {
            Toast.makeText(getApplicationContext(), "Single", Toast.LENGTH_LONG).show();               

        }
    });

But I still have the same problem, it can't distinguish between single and double tap. Single tap is picked up even if I double tap.

I have also seen this question, but still no luck.

Upvotes: 1

Views: 444

Answers (2)

Marcos Vasconcelos
Marcos Vasconcelos

Reputation: 18276

You can achiev it by counting the system milliseconds. (commented in the if)

     ImageView.setOnTouchListener(new View.OnTouchListener() {
long lastDown = 0;
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
    if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){
        long now = System.currentTimeInMillis();
        if(now - lastDown < 500) {
           // the second touch was 500ms less ago 
        }
        lastDown = now;
    }
    return super.onTouch(view, motionEvent);
}
});

Upvotes: 1

Kumar Raj
Kumar Raj

Reputation: 124

For this you need to create Custom Gesture Detector and initialize your interface for single Click,Double Click,long pressed .For Simplicity , Here is your code :

img.setOnTouchListener(new MyTouchDetector(mContext,this));


public class MyTouchDetector extends GestureDetector.SimpleOnGestureListener implements View.OnTouchListener {
    int position;
    private Context mContext;
    private GestureDetector mGestureDetector;
    private ClickDetector clickDetector;



    public MyTouchDetector(Context mContext, ClickDetector clickDetector) {
        this.mGestureDetector = new GestureDetector(mContext, this);
        this.clickDetector = clickDetector;
    }
    @Override
    public boolean onDoubleTap(MotionEvent e) {
        Log.d("onDoubleTap :", "" + e.getAction());
        clickDetector.doubleClick();
        return super.onDoubleTap(e);
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
        Log.d("onSingleTap :", "" + e.getAction());
        clickDetector.singleClick();
        return super.onSingleTapConfirmed(e);
    }

    @Override
    public boolean onDown(MotionEvent e) {
        //return super.onDown(e);
        return true;
    }
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return mGestureDetector.onTouchEvent(event);
    }
    @Override
    public void onLongPress(MotionEvent e) {
        super.onLongPress(e);
        Log.d("onLongPress :", "" + e.getAction());

    } 

Upvotes: 2

Related Questions