Search code examples
androidtouch

How to probably handle different touch events, especially taps and long press on screen?


I'm making an app in which you touch a specific word on the screen and that word gets pronounced. But when I tap on any word, it gets pronounced at least twice and if I hold my finger on the word it gets pronounced so many times and I don't want that. Can I detect the touch as only a tap on the screen? And if the user holds or did a long press, I want something entirely different to happen like copying the word for example.

I tried to do that based on someone's code but both the if and else statements run!

@Override
    public boolean onTouchEvent(MotionEvent event) {

        int touchX = Math.round(event.getX());
        int touchY = Math.round(event.getY());

        long startClickTime = System.currentTimeMillis();


        //words are surrounded with rect objects because i'm using the TextRecognition library that Google provided
        for(int x=0; x< rects.size();x++) {

                if (System.currentTimeMillis() - startClickTime < ViewConfiguration.getTapTimeout()) {

                    // Touch was a simple tap. Do whatever.
                    Log.i("TTS", "Touch was a simple tap!");

                    if (rects.get(x).contains(touchX, touchY)) {
                        // a word has been clicked -> some code to pronounce the word

                        return true;
                } else {

                    // Touch was a not a simple tap.
                        Log.i("TTS", "Touch was a not a simple tap!");
                }
            }
        }

        return super.onTouchEvent(event);
    }

I also tried the onDown(), onShowPress(), onSingleTapUp() and onLongPress() methods but none of them does anything and I don't know why of should i use them better of the onTouchEvent() method.


Solution

  • So, I was able to perfectly handle touch events by implementing the GestureDetector.OnGestureListener methods in conjunction with the onTouchEvent() methods.

        private GestureDetectorCompat mDetector;
        boolean mIsScrolling;
    
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_preview);
    
                // Instantiate the gesture detector with the
                // application context and an implementation of
                // GestureDetector.OnGestureListener
                mDetector = new GestureDetectorCompat(this,this);
    
    
                //set TouchListener on previewLayout
                previewLayout.setOnTouchListener(new View.OnTouchListener() {
                    public boolean onTouch(View v, MotionEvent event) {
    
                        if (mDetector.onTouchEvent(event)) {
                            return true;
                        }
    
                        if(event.getAction() == MotionEvent.ACTION_UP) { //when user left his finger up
                            if(mIsScrolling) { //if it was a scroll action
                                handleScrollFinished();
                                mIsScrolling  = false; //set mIsScrolling back to false
    
                            }
                        }
    
                        return PreviewActivity.super.onTouchEvent(event);
                }
    
                });
    }
    

    .

    @Override
        public boolean onDown(MotionEvent event) {
            //Do stuff
            return true;
        }
    
        @Override
        public boolean onSingleTapUp(MotionEvent event) {
            //So stuff
            return true;
        }
    
        @Override
        public void onLongPress(MotionEvent event) {
            //Do stuff
        }
    
        @Override
        public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
                                float distanceY) {
            mIsScrolling  = true;
    
            //Do stuff
            return true;
        }
    
        private void handleScrollFinished() {
    
            //Do stuff
    
        }
    
        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2,
                               float velocityX, float velocityY) {
            return false; //it has to return false, or I will have to write unnecessary extra code
        }
    
    
        @Override
        public void onShowPress(MotionEvent event) {
        }
    

    Things that helped me through: