【问题标题】:How to probably handle different touch events, especially taps and long press on screen?如何可能处理不同的触摸事件,尤其是点击和长按屏幕?
【发布时间】:2019-08-05 21:17:30
【问题描述】:

我正在制作一个应用程序,您可以在其中触摸屏幕上的特定单词,然后该单词就会发音。但是当我点击任何单词时,它至少会发音两次,如果我将手指放在单词上,它会发音很多次,我不希望这样。我可以将触摸检测为仅在屏幕上点击吗?如果用户按住或长按,我希望发生一些完全不同的事情,例如复制单词。

我尝试根据某人的代码执行此操作,但 if 和 else 语句都运行!

@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);
    }

我还尝试了onDown()onShowPress()onSingleTapUp()onLongPress() 方法,但它们都没有做任何事情,我不知道为什么我应该更好地使用它们而不是onTouchEvent() 方法。

【问题讨论】:

    标签: android touch


    【解决方案1】:

    MotionEvent Actions有多种类型,您可以通过检查事件的动作来区分它们

    @Override
    public boolean onTouchEvent(MotionEvent event) {
     if (event.getAction() == MotionEvent.ACTION_DOWN) {
     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);
    }
    

    【讨论】:

      【解决方案2】:

      您可以在单个视图上使用所有 LongClick、Click 和触摸监听器,我不得不偶尔在项目中使用它,所以 我编写了一个实用程序类来处理单个视图上的单击、保持(长按)开始和保持结束(释放)。

      去看看

      https://github.com/Zohaib-Amir/utility-classes/blob/master/ClickAndHoldManager.java

      ClickAndHoldManager manager = new ClickAndHoldManager(myButton);
      manager.setClickCallback(new View.OnClickListener() {
                  @Override
                  public void onClick(View view) {
                   //Regular Click
                  }
              });
      manager.setHoldCallback(new ClickAndHoldManager.HoldListener() {
                  @Override
                  public void holdStarted() {
                      // this is same as onLongClick
                  }
      
                  @Override
                  public void holdEnded() {
                      // LongClick released
      
                  }
              });
      

      要使用它,只需在构造函数中传递视图并将侦听器添加到管理器。

      您可以通过在 onTouchEvent 中添加更多事件来自定义它。

      (请原谅一些应该是私有的方法)

      【讨论】:

        【解决方案3】:

        因此,我能够通过结合 onTouchEvent() 方法实现 GestureDetector.OnGestureListener 方法来完美处理触摸事件。

            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) {
            }
        

        帮助我度过难关的事情:

        【讨论】:

          猜你喜欢
          • 2011-07-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-27
          • 2021-07-06
          • 2020-11-11
          • 1970-01-01
          相关资源
          最近更新 更多