如何在Android中重复/重新启动onLongClick

时间:2014-10-03 22:21:08

标签: android button repeat onlongclicklistener

你有一个"擦洗"或"扫描"我正在写的音乐播放器上的按钮。如果用户长时间按住按钮,那么我喜欢我的按钮要做的是每隔几秒就会在曲调中前进几毫秒。

如果按住按钮,如何才能获得多个onLongClick()事件?目前我只得到一个,就是这样。必须有一种方法来重置计时器,以便它确实再次发生..我希望?

3 个答案:

答案 0 :(得分:1)

onLongClick()上启动一个定时器,每隔一两秒执行一次跳跃动作。获得ACTION_UP keyEvent时停止计时器。

答案 1 :(得分:1)

如评论所述,您可以收听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;
    }
}); 

答案 2 :(得分:0)

这是我拼凑的解决方案,对我来说效果很好。我会接受以前的答案,但他们没有考虑移动按钮的视图。我希望下面的代码可以帮助其他人摆脱同样的困境。这段代码的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();
  }
}