2010-08-24 131 views
9

我有两个按钮,每按一次按钮就会递增和递减一个值,并且他们在onClickListener中工作得很好。我发现存在一个onLongClickListener,我假设它是用于触摸和保持事件。如果按钮被保持,我将如何快速增加/减少数字?Android长时间触发事件

我正确地认为onLongClickListener只触发一次长按?在我不知道的地方是否有更合适的听众或财产?

+0

使用Handler.sendDelayedMessage()每x毫秒发送一条消息给自己,直到获得up事件。 – hackbod 2010-08-24 05:03:42

+0

尝试使用http://developer.android.com/reference/android/view/View.OnTouchListener.html在ontouch中,它为您提供了一个动作事件。您可以检查行动并采取行动。你基本上实现了触摸和自我摸索 – Falmarri 2010-08-24 02:39:39

+0

所有我想要的是一个x--和一个TextView.setText每200毫秒左右,而按下按钮。我很抱歉我没有那种Java经验,我的大部分经验都是ASP/PHP类型的东西,没有太多的交互性。如果某人可能有示例代码,或者可以用正确的方法指向我,我将不胜感激,但我甚至不知道从哪一个开始。 – 2010-08-24 03:55:10

回答

15

您可以像下面的代码一样实现它。

package org.me.rapidchange; 

import android.app.Activity; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.util.Log; 
import android.view.KeyEvent; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.View.OnKeyListener; 
import android.view.View.OnTouchListener; 
import android.widget.Button; 
import android.widget.TextView; 
import java.util.concurrent.Executors; 
import java.util.concurrent.ScheduledExecutorService; 
import java.util.concurrent.TimeUnit; 

public class MainActivity extends Activity implements OnKeyListener, 
     OnTouchListener, OnClickListener { 
    private class UpdateCounterTask implements Runnable { 
     private boolean mInc; 

     public UpdateCounterTask(boolean inc) { 
      mInc = inc; 
     } 

     public void run() { 
      if (mInc) { 
       mHandler.sendEmptyMessage(MSG_INC); 
      } else { 
       mHandler.sendEmptyMessage(MSG_DEC); 
      } 
     } 
    } 

    private static final int MSG_INC = 0; 
    private static final int MSG_DEC = 1; 

    private Button mIncButton; 
    private Button mDecButton; 
    private TextView mText; 
    private int mCounter; 

    private Handler mHandler; 
    private ScheduledExecutorService mUpdater; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle icicle) { 
     super.onCreate(icicle); 
     setContentView(R.layout.main); 
     mHandler = new Handler() { 
      @Override 
      public void handleMessage(Message msg) { 
       switch (msg.what) { 
        case MSG_INC: 
         inc(); 
         return; 
        case MSG_DEC: 
         dec(); 
         return; 
       } 
       super.handleMessage(msg); 
      } 
     }; 
     mIncButton = (Button) findViewById(R.id.inc_button); 
     mDecButton = (Button) findViewById(R.id.dec_button); 
     mText = (TextView) findViewById(R.id.text); 
     mIncButton.setOnTouchListener(this); 
     mIncButton.setOnKeyListener(this); 
     mIncButton.setOnClickListener(this); 
     mDecButton.setOnTouchListener(this); 
     mDecButton.setOnKeyListener(this); 
     mDecButton.setOnClickListener(this); 
    } 

    private void inc() { 
     mCounter++; 
     mText.setText(Integer.toString(mCounter)); 
    } 

    private void dec() { 
     mCounter--; 
     mText.setText(Integer.toString(mCounter)); 
    } 

    private void startUpdating(boolean inc) { 
     if (mUpdater != null) { 
      Log.e(getClass().getSimpleName(), "Another executor is still active"); 
      return; 
     } 
     mUpdater = Executors.newSingleThreadScheduledExecutor(); 
     mUpdater.scheduleAtFixedRate(new UpdateCounterTask(inc), 200, 200, 
       TimeUnit.MILLISECONDS); 
    } 

    private void stopUpdating() { 
     mUpdater.shutdownNow(); 
     mUpdater = null; 
    } 

    public void onClick(View v) { 
     if (mUpdater == null) { 
      if (v == mIncButton) { 
       inc(); 
      } else { 
       dec(); 
      } 
     } 
    } 

    public boolean onKey(View v, int keyCode, KeyEvent event) { 
     boolean isKeyOfInterest = keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER; 
     boolean isReleased = event.getAction() == KeyEvent.ACTION_UP; 
     boolean isPressed = event.getAction() == KeyEvent.ACTION_DOWN 
       && event.getAction() != KeyEvent.ACTION_MULTIPLE; 

     if (isKeyOfInterest && isReleased) { 
      stopUpdating(); 
     } else if (isKeyOfInterest && isPressed) { 
      startUpdating(v == mIncButton); 
     } 
     return false; 
    } 

    public boolean onTouch(View v, MotionEvent event) { 
     boolean isReleased = event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL; 
     boolean isPressed = event.getAction() == MotionEvent.ACTION_DOWN; 

     if (isReleased) { 
      stopUpdating(); 
     } else if (isPressed) { 
      startUpdating(v == mIncButton); 
     } 
     return false; 
    } 
} 
+0

这很有效,我想我甚至可以理解它是如何工作的,哈哈。谢谢! – 2010-08-24 05:39:43

5

我有同样的目标,结束了使用的OnLongClick赶下部分经处理开始重复事件,那么正常的OnClick赶上释放和停止它。为我工作得很漂亮。

mOngoingRunnable = new Runnable() { 
    public void run() { 
     // do stuff 
     mHandler.postDelayed(mOngoingRunnable, delayMsecs); 
    } 
}; 

public boolean onLongClick(View view) { 
    mHandler.post(mOngoingRunnable); 
    mOngoing = true; 
    return false; 
} 

public void onClick(View view) { 
    if (mOngoing) { 
     mHandler.removeCallbacks(mOngoingRunnable); 
     mOngoing = false; 
    } 
}