我有一个情况,我创建了一个按钮和一个类似这样的功能。
...
public void BtnOnClick(View view) {
displayMsg();
}
...
private void displayMsg(){
handler.postDelayed(new Runnable() {
@Override
public void run() {
Toast.makeText(this, "TestQueue", Toast.LENGTH_SHORT).show();
}
}, 3000);
}
...
如果我单击按钮一次,则在3秒钟的延迟后应该出现一个Toast。 但是,如果我快速单击按钮两次或两次以上,则所有Toast会在3秒后同时出现,而在每次Toast之间都不会延迟3秒,这不好。尽管希望同时点击,但我希望每个Toast外观之间的间隔/延迟为3秒。
有什么解决办法吗?
如果队列中有多个处理程序,则每个处理程序延迟时间在上一个处理程序延迟时间结束之后开始。
答案 0 :(得分:1)
您可以将请求排入队列,以确保间隔显示面包。
ArrayList<Runnable> requests = new ArrayList<>;
bool inProgress = false;
private void displayMsg(){
Runnable runnable = new Runnable() {
@Override
public void run() {
Toast.makeText(this, "TestQueue", Toast.LENGTH_SHORT).show();
inProgress = false;
if (requests.size() > 0) {
handler.postDelayed(requests.remove(0), 3000 + Toast.LENGTH_SHORT);
}
}
}
if (!inProgress) {
inProgress = true;
handler.postDelayed(runnable, 3000);
} else {
requests.add(runnable);
}
}
答案 1 :(得分:1)
尝试一下:
private final Handler handler = new Handler() {
final int DELAY = 3000;
final int DELAY_MSG = 1;
final Queue<Runnable> pendingRunnables = new ArrayDeque<>();
@Override
public void dispatchMessage(Message msg) {
if (msg.what == DELAY_MSG) {
final Runnable r = pendingRunnables.poll();
if (r != null) {
r.run();
sendEmptyMessageDelayed(DELAY_MSG, DELAY);
}
} else {
pendingRunnables.add(msg.getCallback());
if (!hasMessages(DELAY_MSG)) {
sendEmptyMessage(DELAY_MSG);
}
}
}
};
...
// post action
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(this, "TestQueue", Toast.LENGTH_SHORT).show();
}
});
答案 2 :(得分:0)
也许您可以使用postAtTime
:
AtomicLong previous = new AtomicLong(System.currentTimeMillis());
private void displayMsg(){
handler.postAtTime(new Runnable() {
@Override
public void run() {
Toast.makeText(this, "TestQueue", Toast.LENGTH_SHORT).show();
}
}, previous.updateAndGet(operand -> Long.max(operand + 3000, System.currentTimeMillis() + 3000)));
}
答案 3 :(得分:0)
解决方案::您可以使用postDelayed
解决问题:
private long interval = 0;
public void BtnOnClick(View view) {
displayMsg();
}
private void displayMsg() {
interval += 3000;
handler.postDelayed(new Runnable() {
@Override
public void run() {
Toast.makeText(this, "TestQueue", Toast.LENGTH_SHORT).show();
}
}, interval);
}