按下按钮时递增/递减计数器

Vio*_*ion 2 graphics android

我想围绕他的中心旋转图片(ImageView中的位图).通过使用preRotate方法和Bitmap的值width/2和height/2以及1或-1度作为旋转因子,这非常有效.

但我将旋转功能实现为按钮.每次按下"向右旋转"按钮时,Imageview会向右旋转一度,依此类推.按下按钮会很好,按下按钮时图片开始旋转,直到按钮被释放.

我在这里阅读了一些线程,其中这些功能实现为OnTouchListener而不是OnClickListener,但它对我不起作用.如果我在MotionEvent.ACTION_DOWN事件中实现循环,那么它们是无限的.如果我不使用循环,那么事件只处理一次(如在OnClickListener中).

那么在按下按钮时如何增加/减少旋转系数呢?

Kur*_*aum 9

简短回答:您需要实现相应的MotionEvent.ACTION_UP来停止添加.当用户按下时,ACTION_DOWN只被触发一次.这就是为什么当你没有循环时,你只有一个增量.你需要的是一个单独的线程,当MotionEvent.ACTION_DOWN完成时开始进行增量,并在触发MotionEvent.ACTION_UP时停止它们.这样的事情应该有效.

public MyActivity extends Activity{


  private bool continueIncrementing;
  private Runnable incrementerThread;

  //put this OnTouchListener on your button
   View.OnTouchListener downListener = new View.OnTouchListner(){
     public onTouch(View v, MotionEvent event){
       if(event == MotionEvent.ACTION_DOWN){
         startIncrmenting();
       }
       else if(event == MotionEvent.ACTION_UP){
         stopIncrementing();
       }
     }
   };

   private void startIncrmenting(){
     setIsIncrementing(true);
     new Thread(new Runnable() {
       public void run() {
         while(isIncrementing()){
          //do incrementing in here
         }
       }
     }).start();
   }

   sychronized private void stopIncrmenting(){
     setIsIncrementing(false);
   }


   sychronized private bool isIncrmenting(){
     return continueIncrementing;
   }

   synhronized void setIsIncrmenting(bool newSetting){
     continueIncrementing = newSetting;
   }


  //rest of your activity

}
Run Code Online (Sandbox Code Playgroud)


Ner*_*cer 8

我已经将Knickedi的答案扩展到一个更通用的案例.希望能帮助别人.

import android.view.MotionEvent;
import android.view.View;

public abstract class OnTouchContinuousListener implements View.OnTouchListener {

  private final int mInitialRepeatDelay;
  private final int mNormalRepeatDelay;
  private View mView;

  /**
   * Construct listener with default delays
   */
  public OnTouchContinuousListener() {
    this.mInitialRepeatDelay = 500;
    this.mNormalRepeatDelay = 200;
  }

  /**
   * 
   * Construct listener with configurable delays
   * 
   * 
   * @param initialRepeatDelay
   *          delay to the first repeat in millis
   * @param normalRepeatDelay
   *          delay to subsequent repeats in millis
   */
  public OnTouchContinuousListener(int initialRepeatDelay, int normalRepeatDelay) {
    this.mInitialRepeatDelay = initialRepeatDelay;
    this.mNormalRepeatDelay = normalRepeatDelay;
  }

  private final Runnable repeatRunnable = new Runnable() {
    @Override
    public void run() {

      // as long the button is press we continue to repeat
      if (mView.isPressed()) {

        // Fire the onTouchRepeat event
        onTouchRepeat(mView);

        // Schedule the repeat
        mView.postDelayed(repeatRunnable, mNormalRepeatDelay);
      }
    }
  };

  /**
   * Called when a touch event is dispatched to a view. This allows listeners to
   * get a chance to respond before the target view.
   * 
   * @param v
   *          The view the touch event has been dispatched to.
   * @param event
   *          The MotionEvent object containing full information about the
   *          event.
   * @return True if the listener has consumed the event, false otherwise.
   */
  @Override
  public boolean onTouch(View v, MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
      mView = v;

      // Fire the first touch straight away
      onTouchRepeat(mView);

      // Start the incrementing with the initial delay
      mView.postDelayed(repeatRunnable, mInitialRepeatDelay);
    }

    // don't return true, we don't want to disable buttons default behavior
    return false;
  }

  /**
   * Called when the target item should be changed due to continuous touch. This
   * happens at first press, and also after each repeat timeout. Releasing the
   * touch will stop the repeating.
   * 
   */
  public abstract void onTouchRepeat(View view);

}
Run Code Online (Sandbox Code Playgroud)