【问题标题】:How can I create a Single Click Event and Double Click Event when the Menu Button is pressed?按下菜单按钮时如何创建单击事件和双击事件?
【发布时间】:2011-11-08 10:31:18
【问题描述】:

我希望能够在按下菜单按钮时检测单击或双击。如果检测到单击,甚至会发生一个事件,如果检测到双击,则会发生不同的事件。这是我尝试过的(使用 toast 代替事件):

private static final long DOUBLE_PRESS_INTERVAL = 250; // in millis
private long lastPressTime;

@Override
public boolean onPrepareOptionsMenu(Menu menu) {    

    // Get current time in nano seconds.
    long pressTime = System.currentTimeMillis();


    // If double click...
    if (pressTime - lastPressTime <= DOUBLE_PRESS_INTERVAL) {
        Toast.makeText(getApplicationContext(), "Double Click Event", Toast.LENGTH_SHORT).show();
        return true;
    }

    // If not double click....
    Toast.makeText(getApplicationContext(), "Single Click Event", Toast.LENGTH_SHORT).show();

    // record the last time the menu button was pressed.
    lastPressTime = pressTime;      
    return true;
}

问题是每次双击事件之前都会检测到单击事件。

【问题讨论】:

  • 如何检测到长按?我现在正在挖掘文档但没有找到任何有用的东西? (现在长按只会显示键盘)
  • 我想我明白你在说什么。我想要长按物理键盘而不是视图。该视图已经注册了一次长按。

标签: java android click double double-click


【解决方案1】:

我修改了此代码以检测保持事件(长按)以及短按和双击。它的工作原理是将短点击检测延迟到 ACTION_UP 事件,该事件尚未处理 (clickHandled == false)。

为 onShortClick()、onLongClick() 和 onDoubleClick() 提供您自己的方法。

private long thisTouchTime;
private long previousTouchTime = 0;
private long buttonHeldTime;
private boolean clickHandled = false;
private long DOUBLE_CLICK_INTERVAL = ViewConfiguration.getDoubleTapTimeout();
private long LONG_HOLD_TIMEOUT = ViewConfiguration.getLongPressTimeout();

@Override
public boolean onTouch(View v, final MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            thisTouchTime = System.currentTimeMillis();
            if (thisTouchTime - previousTouchTime <= DOUBLE_CLICK_INTERVAL) {
                // double click detected
                clickHandled = true;
                onDoubleClick(event);
            } else {
                // defer event handling until later
                clickHandled = false;
            }
            previousTouchTime = thisTouchTime;
            break;
        case MotionEvent.ACTION_UP:
            if (!clickHandled) {
                buttonHeldTime = System.currentTimeMillis() - thisTouchTime;
                if (buttonHeldTime > LONG_HOLD_TIMEOUT) {
                    clickHandled = true;
                    onLongClick(event);
                } else {
                    Handler myHandler = new Handler() {
                        public void handleMessage(Message m) {
                            if (!clickHandled) {
                                clickHandled = true;
                                onShortClick(event);
                            }
                        }
                    };
                    Message m = new Message();
                    myHandler.sendMessageDelayed(m, DOUBLE_CLICK_INTERVAL);
                }
            }
            break;
        case MotionEvent.ACTION_MOVE:
            myParams.x = initialDrawX + (int) (event.getRawX() - initialTouchX);
            myParams.y = initialDrawY + (int) (event.getRawY() - initialTouchY);
            windowManager.updateViewLayout(v, myParams);
            break;
    }
    return false;
}

【讨论】:

    【解决方案2】:

    简单的逻辑错误。您在记录新的 lastPressTime 之前返回。如果他们都返回相同的东西,你应该只有一个返回调用:

    boolean mHasDoubleClicked = false;
    
        @Override
        public boolean onPrepareOptionsMenu(Menu menu) {    
    
            // Get current time in nano seconds.
            long pressTime = System.currentTimeMillis();
    
    
            // If double click...
            if (pressTime - lastPressTime <= DOUBLE_PRESS_INTERVAL) {
                Toast.makeText(getApplicationContext(), "Double Click Event", Toast.LENGTH_SHORT).show();
                mHasDoubleClicked = true;
            }
            else {     // If not double click....
                mHasDoubleClicked = false;
                Handler myHandler = new Handler() {
                     public void handleMessage(Message m) {
                          if (!mHasDoubleClicked) {
                                Toast.makeText(getApplicationContext(), "Single Click Event", Toast.LENGTH_SHORT).show();
                          }
                     }
                };
                Message m = new Message();
                myHandler.sendMessageDelayed(m,DOUBLE_PRESS_INTERVAL);
            }
            // record the last time the menu button was pressed.
            lastPressTime = pressTime;      
            return true;
        }
    

    【讨论】:

    • 这不会解决问题,因为在双击中第一次按下按钮时,您将运行 'else' 案例并祝酒单单击事件,然后立即执行 'if' 案例.
    • 啊好的,我现在明白了。看看编辑是否更好。我还没有检查它是否编译。
    • handleMessage 声明后缺少一个分号。但它完美无缺。惊人的!在谷歌搜索这个问题的答案时,从未使用过处理程序对象,也从未发现任何关于它的信息。非常感谢!
    • 完美答案。谢谢 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-02
    • 2017-10-25
    • 2014-02-17
    • 2015-02-15
    相关资源
    最近更新 更多