当我按住按钮时,如何获取按钮按下的时间?

11

我有一个按钮,按下并继续按住,如果按住时间超过了某个时间间隔,它会触发某种意图。我该如何实现这个功能?谢谢。


你到目前为止做了什么,请发帖说明。 - Shabbir Dhangot
你应该尝试使用长按监听器。 - GrIsHu
我尝试了LongClickListener,但时间持续不够长。 - RealDream
2
如果按住时间长达5秒钟,则显示Toast。 - RealDream
你可以尝试我的答案。 - Hardik
你找到解决方案了吗?我可能也需要做同样的事情。谢谢。 - Jiajun
6个回答

16

试试这个。

你可以使用Touch Listener来实现这个。

尝试:

Handler handler = new Handler();
    b.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View arg0, MotionEvent arg1) {
            switch (arg1.getAction()) {
            case MotionEvent.ACTION_DOWN:
                handler.postDelayed(run, 5000/* OR the amount of time you want */);
                break;

            default:
                handler.removeCallbacks(run);
                break;

            }
            return true;
        }
    });

在您的情况下,b应该是您想要进行长按的view(通常是一个按钮)。

Runnable run的代码如下:

Runnable run = new Runnable() {

    @Override
    public void run() {
        // Your code to run on long click

    }
};

希望能对您有所帮助... :)


如何每5000个时间单位调用一个事件? - zionpi

7

检测 [ACTION_DOWN][1][ACTION_UP][2] 事件。

当按钮被按下 ([ACTION_DOWN][1]),开始计时,计算时间... 如果计时器超时,则调用 Intent。当按钮被释放 ([ACTION_UP][2]),停止计时器。

final Timer timer = new Timer();
button.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View arg0, MotionEvent arg1) {
        switch ( arg1.getAction() ) {
        case MotionEvent.ACTION_DOWN:
            //start timer
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    // invoke intent
                }
            }, 5000); //time out 5s
            return true;
        case MotionEvent.ACTION_UP:
            //stop timer
            timer.cancel();
            return true;
        }
        return false;
    }
});

1
这不是OP所问的。他需要在按钮仍然按下的情况下,如果经过了一定的时间间隔,则启动操作。 - batbrat
问题出在哪里?如果计时器达到超时时间,这意味着按钮仍然被按下,因为计时器没有在 ACTION_UP 中停止。 - Dario
1
你说得对。你能否在注释中澄清一下这个问题?因为这就是我误解的原因。 - batbrat
2
我也更新了示例,所以希望现在更清楚我想表达的意思。 - Dario

5
long lastDown;
long keyPressedDuration ;

button.setOnTouchListener(new OnTouchListener() {
     @Override
     public boolean onTouch(View v, MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_DOWN) {
           lastDown = System.currentTimeMillis();
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
           keyPressedDuration = System.currentTimeMillis() - lastDown;
        }
     }
  };

2
我认为这并不是OP所要求的,即如果ACTION_DOWN(因为长按而持续)持续时间超过长按持续时间,则启动操作。 - batbrat

0

当我使用计时器时,出现了异常!您也可以像下面这样使用处理程序 -

final Handler handler = new Handler();
final Runnable run = new Runnable(){
        @Override
        public void run() {
            //Do your Stuff!     
        }
    };
    button.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(final View view, MotionEvent motion) {
                switch (motion.getAction() ) {
                    case MotionEvent.ACTION_DOWN:
                        handler.postDelayed(run, 5000); //5 seconds delay
                        return true;

                    case MotionEvent.ACTION_UP:
                        handler.removeCallbacks(run);
                        return true;
                        }
                        return false;
                    }});

0
您可以重写 onTouchEvent 并计算 ACTION_DOWNACTION_UP 之间的偏移量;
下面的代码将在 x 时间后运行一个可运行对象,并在 x 时间之前调用 ACTION_UP 时将其删除。还包括如何获取精确的时间值...
@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
        // record the start time
        mStartTime = ev.getEventTime();
        mHandler.postDelayed(mTaskToRun, MAXIMUM_LONG_PRESS_INTERVAL);
    } else if (ev.getAction() == MotionEvent.ACTION_UP) {
        // record the end time
        mEndTime = ev.getEventTime();

        long keyPressedDuration = mEndTime - mStartTime;

        mHandler.removeCallbacks(mTaskToRun);
    }

    return super.onTouchEvent(ev);
}

你是否正在计算 keyPressedDuration 来检查某个间隔是否已经超过了 ACTION_UP 发生的时间?现在它在你的代码中什么都没有做...此外,MAXIMUM_LONG_PRESS_INTERVAL 是我们定义的,不是吗? - batbrat
使用postDelayed()方法并设置时间间隔后似乎没有任何反应?这里的计算仅供参考,实际工作是由Handler完成的。 - Lunar
我是在说keyPressedDuration没有做任何事情;它被定义并计算了一个值,但在其他地方没有使用。我确实理解处理程序会做这项工作。至于计算只是一个参考,那很好。时间间隔可以由用户定义。这就是我希望你所指的。 - batbrat
啊!我又错过了一件事。你说,“如果在x时间之前调用ACTION_UP,则也将其删除”,但是代码无论经过多长时间都会在ACTION_UP上删除事件。据我所知,这种行为正是OP想要的。然而,你描述的行为需要对keyPressedDuration进行额外的检查,对吗? - batbrat
如果按住时间超过某个时间间隔,则会触发某种意图。如果在 ACTION_UP 被调用之前 MAXIMUM_LONG_PRESS_INTERVAL 过期,则会触发事件。例如,按钮已经按住了“一定时间间隔”。否则,我们不关心,因为它没有达到最小间隔,所以删除延迟任务。 - Lunar
你可能误解了。我很清楚OP想要什么,也确信你的代码示例能够满足OP的需求。但我所指的是你的描述似乎暗示了如果时间已经流逝,则除了其他操作之外还要在ACTION_UP上调用处理程序。 - batbrat

-2

编辑。

显然,我误解了问题。请参见上面的@Hardik和@Lunar的解决方案。


你可以这样做:
button.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        long duration = 0L;

        final int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                duration = SystemClock.elapsedRealtime();
                break;
            case MotionEvent.ACTION_UP:
                duration = SystemClock.elapsedRealtime() - duration;
                break;
            default:
                break;
        }

        if (duration > YOUR_INTERVAL_IN_MILLIS) {
            // Do stuff...
        }

        return true; // or whatever you want to return.
    }
});

谢谢你复制粘贴,但是你的代码不会运行。 - Kanaiya Katarmal
我的回答更多是解决方案的展示,因此未经过测试,绝不是复制粘贴的解决方案。你的踩是个笑话。 - Tadej
请在switch case MotionEvent.ACTION_UP中编写逻辑代码。 - Kanaiya Katarmal
curtisLoew,你的代码并没有回答这个问题,因为它只在 ACTION_UP 发生并经过一定时间后才执行某些操作。@Hardik 和 Lunar 已经发布了解决方案。你可能想要查看那些并提出另一种方法或建议。 - batbrat
1
@batbrat,你是对的,我误解了问题。 - Tadej

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接