簡體   English   中英

如何檢測onTouch()外部是否有東西在觸摸/不觸摸屏幕?

[英]How do I detect if something is touching/not touching the screen outside of onTouch()?

我有一個不斷被調用的方法。

我希望該方法具有以下特點:

if(screen is being touched) {
Do this
}
else {
Do this
}

表達問題的另一種方式是,我希望只要觸摸屏幕就可以發生某些事情,而不僅僅是觸摸屏幕一次就可以發生。

我看着這個問題: 檢測觸摸是否在Android設備屏幕上停止

但是我對答案感到困惑。

您可以使用類似下面的代碼

view.setOnTouchListener(new OnTouchListener () {
    public boolean onTouch(View view, MotionEvent event) {
        switch(event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // The user just touched the screen

                break;
            case MotionEvent.ACTION_UP:
                // The touch just ended

                break;
        }

        return false;
    }
});

您應該將此偵聽器分配給Fragment的根視圖或Activity的裝飾視圖。 您可以通過以下方式獲得此信息:

View view = getWindow().getDecorView();

如果您不只是想對觸摸事件做出反應,而是想知道是否正在以其他方法觸摸屏幕,則只需在偵聽器中分配布爾值標志即可。

編輯

由於您需要在定義的時間間隔連續調用方法,因此建議定義時間間隔

final static long REFRESH_TIME = 100; // miliseconds

然后創建一個Handler

final Handler handler = new Handler();

並定義由Handler調用的Runnable並將調用您的方法

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        // call your method

        handler.postDelayed(this, REFRESH_TIME);
    }
}

在您的OnTouchListener您可以初始化並停止重復

case MotionEvent.ACTION_DOWN:
    handler.post(runnable);
    break;

case MotionEvent.ACTION_UP:
    handler.removeCallbacks(runnable);
    break;

一種實現所需結果的可能方法:嘗試將View置於視圖層次結構的頂部,將其設置為與屏幕大小相同,然后覆蓋視圖的setPressed()方法。 如果按下,則執行某些操作;如果未按下,請執行其他操作:

@Override
    public void setPressed(boolean pressed) {
            if (pressed) {
                do something;
            } else {
                do something else;
            }
        super.setPressed(pressed);
    }

嘗試使用onTouchListener()並實現onTouch(View v, MotionEvent e)來檢查事件ACTION_UPACTION_DOWN

實現示例: Android中的觸摸釋放方法

編輯:

閱讀AsyncTask您與其他人的討論后,我建議您在您的類中使用一個AsyncTask來不斷運行更新循環,如下所示:

private static boolean doUpdate = false;

private class PaddleUpdater extends AsyncTask<String,Void,Void> {
  @Override
  protected Void doInBackground(String... strings) {
    while(true) {
      if(isCancelled()) { break; }
      if(doUpdate) {
        //update paddle
      }
    }
  }
}

//in the constructor, do this
PaddleUpdater pu = new PaddleUpdater();
pu.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

然后在這樣的類中設置一個BroadcastReceiver

public static final String TOUCH_UPDATE = "com.packagename.intent.action.TOUCH_UPDATE";

private class TouchStateReceiver extends BroadcastReceiver {
  @Override
  public void onReceive(Context c, Intent i) {
    Bundle b = i.getExtras();
    if (b != null) {
      doUpdate = b.getBoolean("touch");
    }
  }
}

//in the constructor do this
registerReceiver(new UpdateReceiver(), new IntentFilter(TOUCH_UPDATE));

然后,在您的主要活動中,按照@Lamorack的帖子所述設置您的偵聽器,但添加一個意圖廣播:

view.setOnTouchListener(new OnTouchListener () {
  public boolean onTouch(View view, MotionEvent event) {
      Intent i = new Intent(<ClassName>.TOUCH_UPDATE);
      switch(event.getAction()) {
          case MotionEvent.ACTION_DOWN:
              // The user just touched the screen
              i.putExtra("touch", true);
              sendBroadcast(i);
              break;
          case MotionEvent.ACTION_UP:
              // The touch just ended
              i.putExtra("touch", false);
              sendBroadcast(i);
              break;
      }

      return false;
  }
});

說明:

因此,您需要做的是跟蹤特定狀態。 Android會告訴您何時觸摸屏幕以及何時釋放屏幕,因此我們需要根據這些事件來跟蹤觸摸狀態。 因此,我們設置了一個布爾值來跟蹤該狀態。 觸發觸控盒后,我們會將Intent發送給您的班級,並告訴它將其跟蹤的boolean更改為true 觸發釋放的案例時,我們告訴您的類將其跟蹤的boolean更改為false

該類本身已經啟動了一個AsyncTask ,它將基本上運行直到您手動告訴它停止。 AsyncTask的循環將不斷檢查boolean ,如果為true ,則將執行更新,如果為false ,則將跳過更新。

我們在您的班級中設置的BroadcastReceiver實際上是接收您的觸摸偵聽器發送的Intent的對象。

閱讀Lamorak的答案后,我做了非常相似的事情。 我有一個onTouch方法,具有以下內容:

@Override
public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            bool = true;
            break;
        case MotionEvent.ACTION_UP:
            bool = false;
            break;
    }

    return true;
}

然后在更新方法中,我有:

if(bool) {
// Do something
}
else {
//Do this
}

每當調用onDraw()時(連續),都會調用update方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM