【问题标题】:Adding a wait in a switch / case?在开关/机箱中添加等待?
【发布时间】:2012-06-13 05:50:27
【问题描述】:

当用户点击时,触发案例 MotionEvent.ACTION_DOWN。当点击被释放时,触发案例MotionEvent.ACTION_UP。

我有兴趣确定 ACTION_UP 是否在 ACTION_DOWN 的 3 秒内未触发。意思是,如果用户点击后3秒还没有释放,我想知道,本质上是试图确定长点击。

有没有办法做这样的事情?

   switch (event.getAction()) {
       case MotionEvent.ACTION_DOWN:
       break;
       case MotionEvent.ACTION_UP:
       break;
    }

【问题讨论】:

  • OnLongClickListener 不适用于我正在尝试做的事情。我正在寻找替代品。
  • Handler 用于拖拽事件中的时间(在 Android 中)。一旦我陷入等待和睡眠状态,所以它帮助了我。

标签: java android


【解决方案1】:

通常检测长按的正确方法是实现 View.OnLongClickListener。这比您自己检测更容易且更不容易出错,并且可以确保您的应用与系统的其余部分完美匹配。

对于自定义View,您可以将implements View.OnLongClickListener 添加到您的类声明中,将setOnLongClickListener(this); 添加到构造函数中,并将onLongClick() 方法添加到您的类中:

public boolean onLongClick (View v) {
    // Handle long-click
}

如果您的 View 不是自定义的,您可以像这样添加监听器:

theView.setLongClickable(true);
theView.setOnLongClickListener(new View.OnLongClickListener() {
    public boolean onLongClick(View v) {
        // Handle long-click
    }
});

更新:好的,我已经进行了一些挖掘,虽然这对于我曾经使用过的每个视图都是正确的方法,但实际上它不适用于 SeekBars,这就是提问者正在处理的问题。这个事实没有记录在SeekBar 文档中,但实验表明它是正确的,并且通过源代码挖掘显示了原因:SeekBar.onTouchEvent() 不调用super.onTouchEvent()。如果合适,在View.onTouchEvent() 中调用performLongClick()

如果我必须要实现它,我会使用Handler.postDelayed()。在 ACTION_DOWN 上,我会发布(例如延迟 3000 毫秒)Runnable,它处理长按到Handler,我会在 ACTION_UP 上取消它。因此,任何小于延迟的按下都不会最终调用Runnable,但如果延迟后没有发生 ACTION_UP,则它是。

也就是说,我会提醒您重新考虑这样做。长按SeekBar 是什么意思?如果用户拖动“拇指”的时间超过了延迟时间,那么突然间你就有了一个可能不是故意的长按。您可以在每次移动拇指时取消和重置延迟,需要长按几秒钟才能恰好在一个位置。但是很少有完全静止的;事实上,握住拇指几秒钟不移动它是很困难的。因此,您可以对重置延迟的拇指位置进行最小更改。如果必须,我会这样做,但我必须说这是一种非常奇怪的用户体验。

【讨论】:

  • 如果可能,您还应该添加一个 sn-p。
  • @Roger SeekBarView 的(间接)子类,所以它肯定可以工作。请发布您如何添加侦听器的代码。
  • seekBar1.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { System.out.println("Long Click"); return true; } });
  • @Roger 你可能需要调用 seekBar1.setLongClickable(true);第一的。抱歉,我错过了那部分。
  • 似乎没什么区别。
【解决方案2】:

它简单明了。您需要获取时间戳来评估事件之间的时间差异您可以通过以下示例进行操作:

private static int TIME_MARGIN = 3;  //seconds
private Date d1 = null;

public void OnWhatEverOnClickEvent(Event event){
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
           d1 = new Date();
        break;
        case MotionEvent.ACTION_UP:
           Date d2 = new Date();
           if((d2.getTime() - d1.getTime()) >= (TIME_MARGIN * 1000L)){
               //its a long click due to 3 seconds hold, do something here
           }
        break;
    }
}

但是,正如@Darshan Computing 所说,您最好使用View.OnLongClickListener,这是一种轻松的方法。

【讨论】:

  • 似乎只有在点击被释放后才会触发。我需要知道点击保持 3 秒的时间点,而不是在释放后是否保持 3 秒。
  • 当您按下按钮时,将引发 DOWN 事件,然后设置 d1。但是当您释放按钮时,会引发 UP 事件,并且您正在检查日期对象 (d2-d1) 之间的时间差是否超过 3 秒。我想它只是提供你想要的。
  • 关于何时单击已保持三秒钟。只需在事件方法之外定义一个 Date 对象,并在您遇到 'do something' 的 if 条件时设置它的值。这样就可以知道长点击事件是什么时候计算的
【解决方案3】:

当用户单击时,启动一个新线程来轮询按钮的当前状态(或引入在DOWN 中设置并在UP 中重置的新标志。线程可以轮询此状态或每隔100 毫秒,并使用内部时间戳来确定是否已经过了 3 秒。如果是这样,它可以触发一个新事件以开始长按操作

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-28
    • 1970-01-01
    • 2013-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多