2010-08-24 48 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; 
    } 
}