2

简短版本:我想要一种在 onTouchEvent 上启动基于时间的计数器的方法,并测试在响应之前是否经过了一定的时间,作为手动 LongTouch 检测。

说明:我有一个自定义的 imageView 可以在两根手指上滑入/滑出屏幕。我想向它添加拖动事件,但这些事件需要比长按更快。我可以通过使用每个 onTouchEvent 更新一次的计数器来延迟拖动事件,并且只触发拖动,例如 10 个计数,但计数器只更新触摸事件并且手指必须移动。

如何创建一个基于时间的计数器,一个每秒增加 60 次或类似的活动级别字段?

4

4 回答 4

8

我不确定你的问题,但似乎你正试图在你的 onTouchListener 中实现一个捕捉长点击事件,除非你需要在 ACTION_UP 事件发生之前执行某种逻辑?如果是这样,那与我遇到的问题完全相同。我也尝试过使用 System.nanoTime() 但我发现了一个不那么棘手的方法。您可以使用计时器,您只需将其安排在第一个 ACTION_DOWN 事件上,并在发生任何不利情况时取消它(例如 ACTION_UP 意味着它不是长按而只是单击,或者 ACTION_MOVE 位移超过一定的门槛)。类似于以下内容:

layout.seyOnTouchListener(new OnTouchListener(){
    private Timer longpressTimer; //won't depend on a motion event to fire
    private final int longpressTimeDownBegin = 500; //0.5 s
    private Point previousPoint;

    switch(event.getAction()){

    case MotionEvent.ACTION_DOWN:{
        longPressTimer = new Timer();
        longpressTimer.schedule(new TimerTask(){
            //whatever happens on a longpress
        }, longpressTimeDownBegin);
        return true; //the parent was also handling long clicks
    }
    case MotionEvent.ACTION_MOVE:{
        Point currentPoint = new Point((int)event.getX(), (int)event.getY());

        if(previousPoint == null){
            previousPoint = currentPoint;
        }
        int dx = Math.abs(currentPoint.x - previousPoint.x);
        int dy = Math.abs(currentPoint.y - previousPoint.y);
        int s = (int) Math.sqrt(dx*dx + dy*dy);
        boolean isActuallyMoving = s >= minDisToMove; //we're moving

        if(isActuallyMoving){ //only restart timer over if we're actually moving (threshold needed because everyone's finger shakes a little)
            cancelLongPress();
            return false; //didn't trigger long press (will be treated as scroll)
        }
        else{ //finger shaking a little, so continue to wait for possible long press
            return true; //still waiting for potential long press
        }
    }
    default:{
        cancelLongPress();
        return false;
    }
    }
}
于 2012-07-30T20:41:09.217 回答
1

我解决这个问题的方法是在 Action_Down 发生时将一些布尔值设置为 true。如果 action_up 发生,则将布尔值设置为 false。当 action_down 发生时,还可以将 postDelayed 设置为您想要的任何延迟。在 postdelayed 中,如果您之前设置为 true 的布尔值仍然为 true,则执行您想要的操作。抱歉这么冗长的回答,但我就是这样做的。

于 2012-04-06T18:33:10.873 回答
1

只需查看android的源代码即可。

在 GestureDetector 中长按会在“key down”上启动延迟消息。当此消息在“key up”之前出现时,它是长按。

只是指向源 http://www.devdaily.com/java/jwarehouse/android/core/java/android/view/GestureDetector.java.shtml的链接

于 2012-04-06T18:25:14.190 回答
0

答:使用系统时钟 (elapsedRealtime()) 并测量自按下启动以来的毫秒数。一旦你开始掌握它就很容易了。

于 2013-01-28T20:59:46.167 回答