我的UI上有一个SeekBar。当我改变它的位置时,我想在TextView中报告它的值。在这个TextView中,我还想提供一个信息,位置还有多长(以秒为单位)。我想,Runnable中的run方法只运行一次,但每次postDelayed执行时会运行几次。无论延迟是1秒还是10秒。如何强制它只运行一次?我应该制作一个帖子吗?
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
y=0;
myHandler.postDelayed(new Runnable(){
@Override
public void run(){
myHandler.postDelayed(this, 1000);
progressIndicator.setText("Covered: " + progressX.getProgress() + "/" + progressX.getMax() + " position is still for " + y + " seconds");
y+=1;
}
},1000);
}
编辑: removeCallbacks帮助了一下。代码工作正常,但只是在第一次进展时才改变,我明天会试着弄明白。
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
y=0;
myHandler.postDelayed(new Runnable(){
@Override
public void run(){
myHandler.removeCallbacks(this);
y+=1;
progressIndicator.setText("Covered: " + progressX.getProgress() + "/" + progressX.getMax() + " position is still for " + y + " seconds");
myHandler.postDelayed(this, 5000);
}
},5000);
}
答案 0 :(得分:1)
问题是,每个事件 onProgressChanged 同时运行新的runnable。在运行方法中放置 myHandler.removeCallbacks(可运行),产生了一些积极的效果,它是唯一一个“正确”工作的地方。实际上, y 非常快,增加了我们之前和当前搜索栏位置的delta值( postDelayed 方法的累积),之后,它增加了每秒1。 removeCallbacks 杀死了之前的 postDelayed 操作。
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
y=0;
myHandler.postDelayed(new Runnable(){
@Override
public void run(){
myHandler.removeCallbacks(runnable);
...
y+=1;
runnable=this;
myHandler.postDelayed(runnable, 1000);
}
},1000);
然而,这是解决方案,将 myHandler.removeCallbacksAndMessages(null)放在 onProgressChanged 帮助中。 我附上代码以便更好地理解。 TextView progressIndicator 显示,您在搜索栏的当前位置停留多长时间(以秒为单位)。
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
myHandler.removeCallbacksAndMessages(null);
y=0;
progressIndicator.setText("Covered: " + progressX.getProgress() + "/" +
progressX.getMax());
myHandler.postDelayed(new Runnable(){
@Override
public void run(){
y+=1;
progressIndicator.setText("Covered: " + progressX.getProgress() + "/" +
progressX.getMax() + " position is still for " + y + " seconds");
runnable=this;
myHandler.postDelayed(runnable, 1000);
}
},1000);
答案 1 :(得分:0)
您基本上使用模式永远重复Runnable
。在Runnable
内,您可以拨打mHandler.postDelayed(this, 1000);
。此上下文中的this
是您最初创建的new Runnable
。这意味着Runnable
将在每次执行后一秒钟安排另一次运行。
如果您只想运行一次,则应该删除mHandler.postDelayed(this, 1000);
行。
您还应确保在mHandler.removeCallbacks(null)
中致电onDestroy()
,以确保不会导致内存泄漏,因为Runnable
将引用您的Activity
通过TextView
引用。
答案 2 :(得分:0)
onProgressChanged
,这意味着您有几个待处理的postDelayed()
要解决此问题,每次拨打postDelayed()
时,都应先拨打removeCallbacks()
,以确保只有一个待处理的postDelayed()
处于有效状态
但是你需要在类字段中创建Runnable和Handler实例,而不是在onProgressChanged
主体上创建
这样的事情:
private Handler myHandler = new Handler();
private Runnable myRunnable = new Runnable() {
@Override
public void run() {
// do something //
myHandler.removeCallbacks(myRunnable);
myHandler.postDelayed(myRunnable, 1000);
}
};
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// do something //
myHandler.removeCallbacks(myRunnable);
myHandler.postDelayed(myRunnable, 1000);
}