【问题标题】:Single method to implement onTouchListener() for multiple buttons为多个按钮实现 onTouchListener() 的单一方法
【发布时间】:2013-07-25 16:53:50
【问题描述】:

我正在尝试查看是否有一种方法可以创建一个方法来实现多个按钮的触摸侦听器,因为我有很多按钮可以做几乎完全相同的事情。他们所做的唯一区别是他们将通过我的 sendMessage() 方法发送的消息,以及需要按住按钮多长时间才能发送消息。如果有办法做到这一点,那可能是什么?而且,为什么这样的东西不起作用?

//Within onCreate Method...
Button mButton = (Button) findViewbyId(R.id.three_sec_button);
mButton = addTouchTimer(mButton, 3, 3);

通话 -

private Button addTouchTimer(Button button, final int sec, final int messageNum){
        button.setOnTouchListener(new View.OnTouchListener() {
            boolean longEnough = false;
            long realTimeLeft = sec * 1000;
            @Override
            // This will make it so that a message is only sent if the button is held down for 3 seconds
            // Otherwise it won't send. It is sent during the hold down process, releasing it returns a false
            // value and no message is sent.
            public boolean onTouch(View arg0, MotionEvent arg1) {
                Log.d("Button", "Touchy Touchy!");
                if(arg1.getAction() == MotionEvent.ACTION_DOWN){
                    buttonPressTime = new CountDownTimer(realTimeLeft, 1000){
                        @Override
                        public void onTick(long millisUntilDone){
                                realTimeLeft = millisUntilDone;
                        }

                        @Override
                        public void onFinish() {  
                            long timeLeft = realTimeLeft;
                            long currTime = System.currentTimeMillis();
                            long realFinishTime = currTime + timeLeft;
                                while(currTime < realFinishTime){
                                    currTime = System.currentTimeMillis();
                                }
                            longEnough = true;
                            sendEmergencyMessage(longEnough, messageNum);
                        }
                    }.start();
                }
                else if(arg1.getAction() == MotionEvent.ACTION_UP){
                    buttonPressTime.cancel();
                    sendMessage(longEnough, messageNum);
                }
                return longEnough;
            }           
        });

        return button;
    }

似乎为了提高效率,必须有一种比为每个按钮实现单独的侦听器更好的方法。需要注意的是, sendMessage() 在其中有一个使用布尔值的 Log 调用,我想看看它在传递时的设置。这是在按钮释放期间调用它的唯一原因。

【问题讨论】:

    标签: android button ontouchlistener


    【解决方案1】:

    是的,你是对的,有更好的方法。一个处理所有事情的 TouchListener,通过 id 确定它是哪个按钮。

    void intialization(){
         Button m1, m2, m3, m4;
         ... //do initialization stuff
         m1.setId(1);
         m2.setId(2);
         m3.setId(3);
         m4.setId(4);
         MyTouchListener touchListener = new MyTouchListener();
         m1.setOnTouchListener(touchListener);
         m2.setOnTouchListener(touchListener);
         m3.setOnTouchListener(touchListener);
         m4.setOnTouchListener(touchListener);
     }
    
    public class MyTouchListener implements OnTouchListener {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch(v.getId()){
                case 1:
                    //do stuff for button 1
                    break;
                case 2:
                    //do stuff for button 2
                    break;
                case 3:
                    //do stuff for button 3
                    break;
                case 4:
                    //do stuff for button 4
                    break;
            }
            return true;
        }
    
    }
    

    你就是这样做的!在这种情况下,id 的数值方法非常有用。另一种方法是让您的 Activity 在您的 Activity 中实现 OnTouchListener,然后您的代码会更简单。

    public class MyActivity extends Activity implements OnTouchListener {
    
        void initialization(){
            Button m1, m2, m3, m4;
            ... //do initialization stuff
            m1.setId(1);
            m2.setId(2);
            m3.setId(3);
            m4.setId(4);
            m1.setOnTouchListener(this);
            m2.setOnTouchListener(this);
            m3.setOnTouchListener(this);
            m4.setOnTouchListener(this);
        }
    
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch(v.getId()){
                case 1:
                    //do stuff for button 1
                    break;
                case 2:
                    //do stuff for button 2
                    break;
                case 3:
                    //do stuff for button 3
                    break;
                case 4:
                    //do stuff for button 4
                    break;
            }
            return true;
        }
    
    }
    

    注意:此方法也适用于 OnClickListener、OnCheckedChangeListener 或您将在 Android 视图上设置的任何其他侦听器。

    【讨论】:

    • 伙计,我可能在电脑前坐得太久了。应该知道这个。然而,问。你的意思是我应该实现一个名为 MyTouchListener 的新类,还是你只是随意添加它?我不能只做下面所说的并在我的主类中实现它,然后调用 onTouch 方法,如“m1.setOnTouchListener(onTouch());
    • 你可以让你的主要活动实现触摸监听。并可以看到我的答案以供参考。
    • @zgc7009 :如果我们已经解决了您的问题,请接受其中一个作为答案。它对其他人有用。
    • @zgc7009 你可以随意称呼它。重要的部分是它实现了 OnTouchListener
    • 我正在努力让它工作,当我得到一个为我工作时我会接受一个:)
    【解决方案2】:

    使用 ButterKnife 会是这样。 (在我的情况下 ImageView 为按钮)

    @OnTouch({R.id.Button1, R.id.Button2, R.id.Button3})
    public boolean buttonsTouched(ImageView button, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                --(Your ACTION on Pressed)--
                return true;
            case MotionEvent.ACTION_UP:
                --(Your ACTION on Release)--
                return true;
        }
        return true;
    }
    

    【讨论】:

      【解决方案3】:

      是的,有更好的方法来做同样的事情。
      1) 让你的班级实现OnTouchListener.
      2)将此侦听器添加到应处理触摸事件的每个按钮。像这样:

      button1.setOnTouchListener(this);
      

      3) 在这个public boolean onTouch(View arg0, MotionEvent arg1) {});

      你可以在被触摸的视图上使用 switch case 的方法。第一个参数,即arg0 是触摸事件被分派到的视图。在您的情况下,它将是不同的按钮。 像这样的:

      public boolean onTouch(View arg0, MotionEvent arg1) {
          if (arg1.getAction() == MotionEvent.ACTION_DOWN) {
              switch (arg0.getId()) {
              case R.id.button1: // Id of the button
                  // Your code goes here
                  break;
      
              case R.id.button2: // Id of the button
                  // Your code goes here
                  break;
      
              default:
                  break;
              }
          }
          return true;
      }
      

      【讨论】:

      • 这也有效,我将您的答案与上述答案混合并匹配,特别是利用 setId() getId()。他的有点早,所以我给了他支票,但这也很好用。如果可以的话,我会给你们两个批准。
      • 完全没问题 :)
      【解决方案4】:
      OnTouchListener mOnTouchListener = new OnTouchListener() {
      
          @Override
          public boolean onTouch(View v, MotionEvent event) {
              // Code goes here
          return true;
          }
      };
      
      button1.setOnTouchListener(mOnTouchListener);
      button2.setOnTouchListener(mOnTouchListener);
      

      【讨论】:

        【解决方案5】:

        我合并两个答案, 这是我的代码

        public class MyActivity extends Activity implements OnTouchListener {
        Button mGreen, mRed;
        
        void initialization() {
        
            ... //do initialization stuff
        
            mGreen.setOnTouchListener(this);
            mRed.setOnTouchListener(this);
        }
        
        @Override
        public boolean onTouch(View v, MotionEvent event) {
        
        
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN:
                    actionDown();
                    break;
                case MotionEvent.ACTION_UP:
                    actionUp();
                    break;
        
                case MotionEvent.ACTION_POINTER_DOWN:
                    break;
        
                case MotionEvent.ACTION_POINTER_UP:
                    break;
        
                case MotionEvent.ACTION_MOVE:
                    actionMove();
                    break;
            }
        
            return true;
        }
        
        public void actionDown() {
            switch (view.getId()) {
                case R.id.button_green:
                    //todo
                    break;
        
                case R.id.button_red:
                    //todo
                    break;
            }
        }
        
        public void actionUp() {
            switch (view.getId()) {
                case R.id.button_green:
                    //todo
                    break;
        
        
                case R.id.button_red:
                    //todo
                    break;
            }
        }
        
        public void actionMove() {
            switch (view.getId()) {
                case R.id.button_green:
                    // todo
                    break;
        
                case R.id.button_red:
                    // todo
                    break;
            }
        
        }}
        

        我希望这段代码对某人有所帮助

        【讨论】:

          【解决方案6】:

          你为什么不用黄油刀?

          @Nullable @OnClick({R.id.btn1, R.id.btn2,R.id.btn3, R.id.btn4})
          public void doStuff(Button button) {}
          

          【讨论】:

          • 不是onTouchEvent监听器
          • @OnTouch(R.id.view_thing) public boolean onTouch(View view, MotionEvent motionEvent) { }
          【解决方案7】:
          @Override
                  public boolean onTouch(View view, MotionEvent motionEvent)
                  {
                      switch (motionEvent.getAction() & MotionEvent.ACTION_MASK)
                      {
                          case MotionEvent.ACTION_DOWN:
                              shouldClick = true;
                              .
                              .
                              break;
                          case MotionEvent.ACTION_UP:
                              if (shouldClick)
                                  view.performClick();
                              break;
                          case MotionEvent.ACTION_POINTER_DOWN:
                              break;
                          case MotionEvent.ACTION_POINTER_UP:
                              break;
                          case MotionEvent.ACTION_MOVE:
                              //Do your stuff
                              shouldClick = false;
                              break;
                      }
                      rootLayout.invalidate();
                      return true;
                  }
          

          【讨论】:

            【解决方案8】:

            在我的情况下,我需要的与上面的答案相似,但我的目的不同......

            我想在你触摸屏幕时隐藏我的键盘,无论 UP 还是 DOWN

               /**
                 * Hide keyboard on touching the screen
                 * <a href="https://stackoverflow.com/questions/17864143/single-method-to-implement-ontouchlistener-for-multiple-buttons">how to hide on touch</a>
                 */
                @OnTouch(R.id.scroll_sign_up_step2_view)
                public boolean hideKeyBoardOnTouch() {
                    hideKeyboard();
                    return true;
                }
            

            【讨论】:

              【解决方案9】:

              在 Kotlin 中,您可以使用 onTouch 变量创建对象类,然后在您想要的任何地方使用它。

              在 Listeners.kt 中

              object Listeners {
                  val onTouch = View.OnTouchListener { v: View, event: MotionEvent ->
                      //Do anything with view here and check event type
                      return@OnTouchListener false
                  }
              }
              

              然后在你的活动中

              
              button.setOnTouchListener(Listeners.onTouch)
              
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2013-03-27
                • 1970-01-01
                • 2012-05-08
                • 2019-11-10
                • 2010-09-09
                • 2019-02-13
                • 2021-04-07
                • 1970-01-01
                相关资源
                最近更新 更多