在Android中点击屏幕5次3秒内

i1icjdpr  于 2023-05-12  发布在  Android
关注(0)|答案(5)|浏览(218)

我正在开发一个亭,现在在管理方面。为了进入管理员,用户需要在3秒内点击屏幕5次否则,什么都不会发生。

odopli94

odopli941#

请阅读代码中的注解,它相当直接

import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
 
public class MainActivity extends Activity {
   
private int tapCount = 0;
private long tapCounterStartMillis = 0;

//detect any touch event in the screen (instead of an specific view)

@Override
public boolean onTouchEvent(MotionEvent event) {  
    
    int eventaction = event.getAction();
     if (eventaction == MotionEvent.ACTION_UP) {
     
     //get system current milliseconds
     long time= System.currentTimeMillis();

     //if it is the first time, or if it has been more than 3 seconds since the first tap ( so it is like a new try), we reset everything 
     if (tapCounterStartMillis == 0 || (time-tapCounterStartMillis > 3000) ) {
         tapCounterStartMillis = time;
         tapCount = 1;
     }
     //it is not the first, and it has been  less than 3 seconds since the first
     else{ //  time-tapCounterStartMillis < 3000   
         tapCount ++;
     }
     
     if (tapCount == 5) {
        //do whatever you need
     }
     return true;    
    }
    return false;
  }
vbkedwbf

vbkedwbf2#

我的解决方案类似于Andres's。倒计时开始时,你抬起手指第一次,也就是说,当我认为水龙头完成。这与单击类似,释放鼠标按钮时会发生单击。第一次提升3秒后,计数器复位。另一方面,安德烈斯的方法使用的逻辑是将手指放在屏幕上。它还使用了一个额外的线程。
我的逻辑是许多可能的逻辑之一。另一种合理的方法将是在敲击流中在3秒内检测5次连续敲击。考虑:

  • tap1*、2000ms、tap2、500ms、tap3、550ms、tap4、10ms、tap5、10ms、tap6

第二次至第六次敲击包括在小于3秒内的一组五次敲击;在我的方法中,这将不会被检测到。要检测到这一点,您可以使用固定大小为5的FIFO队列,并记住最后5个时间戳:该序列正在增加。当您收到一个新的点击,您检查是否1)有至少5个点击发生,和2)最旧的时间戳是不是旧的3秒。
无论如何,回到第一个逻辑,将此代码放入Activity中:

private int mCounter = 0;
private Handler mHandler = new Handler();

private Runnable mResetCounter = new Runnable() {
    @Override
    public void run() {
        mCounter = 0;
    }
};

@Override
public boolean onTouchEvent(MotionEvent event) {
    switch(MotionEventCompat.getActionMasked(event)) {
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
            if (mCounter == 0)
                mHandler.postDelayed(mResetCounter, 3000);

            mCounter++;

            if (mCounter == 5){
                mHandler.removeCallbacks(mResetCounter);
                mCounter = 0;
                Toast.makeText(this, "Five taps in three seconds", Toast.LENGTH_SHORT).show();
            }

            return false;

        default : 
            return super.onTouchEvent(event);
    }
}

注意:您可能也希望在配置更改时保留一些状态。就像数学家会说的那样,我把它作为一个练习留给读者

g0czyy6m

g0czyy6m3#

覆盖Activity onTouchEvent()方法以从屏幕接收触摸事件。每次用户点击屏幕时,如果是第一次触摸,则递增一个变量并推迟3秒内的Runnable,如果3秒过去,则触摸事件将被清除,什么也不会发生。线程检查触摸事件数是否为5或更多,如果它们发生在3秒之前,则变量未被清除并且if(touchEvent >= 5)条件为真。我还没试过!但它是完全异步的:)

// Touch events on screen
@Override
public boolean onTouchEvent(MotionEvent event) {
        // User pressed the screen
        if(event.getAction() == MotionEvent.ACTION_DOWN){
          if(touchEvent == 0) myView.post(mRunnable, 3000);  // Execute a Runnable in 3 seconds
          ++touchEvent;
        }
        return false;
}

Runnable mRunnable = new Runnable(){
        @Override
        public void run() {
           touchEvent = 0; // 3 seconds passed, clear touch events
        }
}

Thread mThread = new Thread(new Runnable(){
   @Override
   public void run(){
      if(touchEvent >= 5){
         // Touched 5 times in 3 seconds or less, CARE this is not UI Thread!
      }
   }
});
mThread.start();
koaltpgm

koaltpgm4#

如果要在Kotlin中检测视图上的触摸

private var count = 0
private var startMillis: Long = 0
        
textView.setOnTouchListener { v, event ->
        if (event.action == MotionEvent.ACTION_UP) {
            val currentTime = System.currentTimeMillis()
            if (startMillis == 0L || currentTime - startMillis > 3000) {
                startMillis = currentTime
                count = 1
            } else {
                count++
            }
            if (count == 4) {
                
            }

            logd("count -- $count")
        }
        false
    }

在Java中:https://stackoverflow.com/a/21104386/10784151

deyfvvtc

deyfvvtc5#

private int touchSequenceCount = 0;
private Handler handlerTouchSequenceDetection;
private Runnable runnableTouchSequenceDetection;

public void setupTouchSequenceDetection(final View view){

    try {   

        view.setOnTouchListener(new View.OnTouchListener() {               
            public boolean onTouch(View v, MotionEvent event) {             

                int action = event.getAction();

                switch (action) {

                    case MotionEvent.ACTION_DOWN:

                        Log.d("setupTouchSequenceDetection", "touchCount: " + (touchSequenceCount+1));

                        if(touchSequenceCount == 0){

                            handlerTouchSequenceDetection.postDelayed(runnableTouchSequenceDetection, 2000);    

                        }else{

                            if(touchSequenceCount == 2){        

                                new AlertDialog.Builder(Activity_CheckIn_SelectLanguage.this)
                                .setMessage("warning message here")
                                .setCancelable(true)
                                .setPositiveButton("yes", new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int id) {

                                        resetTouchSequenceDetection(true);
                                    }
                                })
                                .setNegativeButton("no", new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int id) {

                                        resetTouchSequenceDetection(true);
                                    }
                                }).setOnCancelListener(new DialogInterface.OnCancelListener() {

                                    @Override
                                    public void onCancel(DialogInterface dialog) {

                                        resetTouchSequenceDetection(true);
                                    }
                                })
                                .show();
                            }

                        }

                        touchSequenceCount = touchSequenceCount + 1;

                    break;
                } 

                return false;
            }
        });

        handlerTouchSequenceDetection = new Handler(); 

        runnableTouchSequenceDetection = new Runnable() { 
             public void run() { 

                 Log.d("setupTouchSequenceDetection", "reset touchCount: " + (touchSequenceCount+1));

                 resetTouchSequenceDetection(false);
             } 
        };

    }
    catch(Exception ex){

        if(ex != null){

        }
    }
}

private void resetTouchSequenceDetection(boolean removeRunnable){

    try{

        if(removeRunnable){
            handlerTouchSequenceDetection.removeCallbacks(runnableTouchSequenceDetection);
        }

        touchSequenceCount = 0; 

    }
    catch(Exception ex){

        if(ex != null){

        }
    }
}

相关问题