【问题标题】:How can I repeat/retrigger onLongClick in Android如何在 Android 中重复/重新触发 onLongClick
【发布时间】:2014-10-03 22:21:08
【问题描述】:

您好,我正在编写的音乐播放器上有一个“擦洗”或“扫描”按钮。如果用户长时间按住按钮,我希望我的按钮每隔几秒就跳几毫秒。

如果我按住按钮,如何让多个 onLongClick() 事件发生?目前我只得到一个,仅此而已。一定有办法重置计时器,这样它肯定会再次发生……我希望?

【问题讨论】:

  • 只需捕获 KeyEvent ACTION_UP 即可停止扫描

标签: android button repeat onlongclicklistener


【解决方案1】:

在onLongClick() 上启动一个计时器,每隔一两秒执行一次你的跳跃动作。当您收到ACTION_UP keyEvent 时停止计时器。

【讨论】:

    【解决方案2】:

    如评论中所说,您可以监听onLongClick(),然后在ACTION_UP 事件上停止移动光标:

    v.setOnKeyListener(new OnKeyListener() {    
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if(KeyEvent.ACTION_UP == event.getAction())
                if(isMoving)
                {
                    isMoving = false;
                    stopMovingCursor();
                }
    
            return false;
        }
    });
    
    v.setOnLongClickListener(new OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            isMoving = true;
            startMovingCursor();
            return false;
        }
    }); 
    

    【讨论】:

    • 谢谢。我会试试这个。几天前,我实现了一个 Button 的子类,但它的问题是你可以触摸,离开按钮,然后触摸,重复将永远持续下去。我会试一试,然后告诉你。
    【解决方案3】:

    这是我拼凑起来的解决方案,对我来说效果很好。我会接受以前的答案,但他们没有考虑到按钮视图之外的移动。我希望下面的代码可以帮助其他人摆脱同样的困境。 90% 的代码不是我的 - 非常感谢提供此代码的其他 stackoverflow 帖子。

    编辑:实际上,这也不完美 - 它不会为按钮触摸设置动画。

    import android.content.Context;
    import android.graphics.Rect;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.Button;
    
    public class AutoRepeatButton extends Button
    {
    
      private long     initialRepeatDelay                 = 500;
      private long     repeatIntervalInMilliseconds       = 1000;
      private boolean  mRepeatStarted = false;
    
      private Runnable repeatClickWhileButtonHeldRunnable = new Runnable()
                                                          {
                                                            @Override
                                                            public void run()
                                                            {
                                                              // Perform the present
                                                              // repetition of the
                                                              // click action
                                                              // provided by the
                                                              // user
                                                              // in
                                                              // setOnClickListener().
                                                              mRepeatStarted = true;
    
                                                              performLongClick();
    
                                                              // Schedule the next
                                                              // repetitions of the
                                                              // click action, using
                                                              // a faster repeat
                                                              // interval than the
                                                              // initial repeat
                                                              // delay interval.
                                                              postDelayed( repeatClickWhileButtonHeldRunnable, repeatIntervalInMilliseconds );
                                                            }
                                                          };
    
      private void commonConstructorCode()
      {
        mRepeatStarted = false;
    
        this.setOnTouchListener( new OnTouchListener()
        {
          @Override
          public boolean onTouch( View v, MotionEvent event )
          {
            int action = event.getAction();
    
            if( action == MotionEvent.ACTION_DOWN )
            {
              // Just to be sure that we removed all callbacks,
              // which should have occurred in the ACTION_UP
              removeCallbacks( repeatClickWhileButtonHeldRunnable );
    
              // Schedule the start of repetitions after a one half second delay.
              postDelayed( repeatClickWhileButtonHeldRunnable, initialRepeatDelay );
            }
            else
            if( action == MotionEvent.ACTION_UP )
            {
              // Cancel any repetition in progress.
              removeCallbacks( repeatClickWhileButtonHeldRunnable );
    
              if( mRepeatStarted == false )
              {
                // PDS: I put this here..
                performClick();
              }
    
              mRepeatStarted = false;      
              return true;
            }
            else    
            if( action == MotionEvent.ACTION_MOVE )
            {
              int[] l = new int[2];
              v.getLocationOnScreen( l );
    
              Rect rect = new Rect( l[0], l[1], l[0] + v.getWidth(), l[1] + v.getHeight() );
    
              if( ! rect.contains( v.getLeft() + (int) event.getX(),
                                   v.getTop()  + (int) event.getY())) 
              {
                // User moved outside bounds
                removeCallbacks( repeatClickWhileButtonHeldRunnable );
    
                mRepeatStarted = false;
              }
            }
            else
            if( action == MotionEvent.ACTION_CANCEL )
            {
              removeCallbacks( repeatClickWhileButtonHeldRunnable );
    
              mRepeatStarted = false;
            }
    
            // Returning true here prevents performClick() from getting called
            // in the usual manner, which would be redundant, given that we are
            // already calling it above.
            return true;
          }
        } );
      }
    
      public AutoRepeatButton( Context context, AttributeSet attrs, int defStyle )
      {
        super( context, attrs, defStyle );
        commonConstructorCode();
      }
    
      public AutoRepeatButton( Context context, AttributeSet attrs )
      {
        super( context, attrs );
        commonConstructorCode();
      }
    
      public AutoRepeatButton( Context context )
      {
        super( context );
        commonConstructorCode();
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多