有人能给出一个简单的例子,每秒钟更新一个文本框左右?
我想要制作一个飞行的球,并需要每秒计算/更新球的坐标,这就是为什么我需要某种计时器。
我从这里什么也得不到。
有人能给出一个简单的例子,每秒钟更新一个文本框左右?
我想要制作一个飞行的球,并需要每秒计算/更新球的坐标,这就是为什么我需要某种计时器。
我从这里什么也得不到。
当前回答
您希望UI更新发生在已经存在的UI线程中。
最好的方法是使用一个Handler,它使用postDelayed在延迟后运行一个Runnable(每次运行都安排下一次运行);使用removeCallbacks清除回调。
您已经找到了正确的地方,所以再看一遍,也许可以弄清楚为什么代码示例不是您想要的。(请参见从计时器更新UI的同一篇文章)。
其他回答
我很惊讶,没有答案会提到RxJava2的解决方案。它真的很简单,提供了一个简单的方法来设置计时器在Android。
首先你需要设置Gradle依赖,如果你还没有这样做:
implementation "io.reactivex.rxjava2:rxjava:2.x.y"
(将x和y替换为当前版本号)
因为我们只有一个简单的,非重复的TASK,我们可以使用Completable对象:
Completable.timer(2, TimeUnit.SECONDS, Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(() -> {
// Timer finished, do something...
});
对于重复TASK,你可以用类似的方式使用Observable:
Observable.interval(2, TimeUnit.SECONDS, Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(tick -> {
// called every 2 seconds, do something...
}, throwable -> {
// handle error
});
Schedulers.computation()确保我们的计时器在后台线程上运行,. observveon (AndroidSchedulers.mainThread())意味着我们在计时器结束后运行的代码将在主线程上完成。
为了避免不必要的内存泄漏,您应该确保在Activity/Fragment被销毁时取消订阅。
他是更简单的解决方案,工作在我的应用程序。
public class MyActivity extends Acitivity {
TextView myTextView;
boolean someCondition=true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
myTextView = (TextView) findViewById(R.id.refreshing_field);
//starting our task which update textview every 1000 ms
new RefreshTask().execute();
}
//class which updates our textview every second
class RefreshTask extends AsyncTask {
@Override
protected void onProgressUpdate(Object... values) {
super.onProgressUpdate(values);
String text = String.valueOf(System.currentTimeMillis());
myTextView.setText(text);
}
@Override
protected Object doInBackground(Object... params) {
while(someCondition) {
try {
//sleep for 1s in background...
Thread.sleep(1000);
//and update textview in ui thread
publishProgress();
} catch (InterruptedException e) {
e.printStackTrace();
};
return null;
}
}
}
import kotlin.concurrent.fixedRateTimer
val timer = fixedRateTimer("Tag", false, 1000, 2500) { /* Your code here */ }
Kotlin非常简单
这里是解决方案,您需要在代码中添加以下类。您可以直接向XML文件添加视图。
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
public class TimerTextView extends TextView {
private static final int DEFAULT_INTERVAL = 1000;
private Timer timer = new Timer();
private long endTime = 0;
private long interval = DEFAULT_INTERVAL;
private boolean isCanceled = false;
public TimerTextView(Context context) {
super(context);
}
public TimerTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TimerTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public TimerTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
stopTimer();
}
@Override protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
if (VISIBLE == visibility) {
startTimer();
} else {
stopTimer();
}
}
public void setInterval(long interval) {
if (interval >= 0) {
this.interval = interval;
stopTimer();
startTimer();
}
}
public void setEndTime(long endTime) {
if (endTime >= 0) {
this.endTime = endTime;
stopTimer();
startTimer();
}
}
private void startTimer() {
if (endTime == 0) {
return;
}
if (isCanceled) {
timer = new Timer();
isCanceled = false;
}
timer.scheduleAtFixedRate(new TimerTask() {
@Override public void run() {
if (null == getHandler()) {
return;
}
getHandler().post(new Runnable() {
@Override public void run() {
setText(getDurationBreakdown(endTime - System.currentTimeMillis()));
}
});
}
}, 0, interval);
}
private void stopTimer() {
timer.cancel();
isCanceled = true;
}
private String getDurationBreakdown(long diff) {
long millis = diff;
if (millis < 0) {
return "00:00:00";
}
long hours = TimeUnit.MILLISECONDS.toHours(millis);
millis -= TimeUnit.HOURS.toMillis(hours);
long minutes = TimeUnit.MILLISECONDS.toMinutes(millis);
millis -= TimeUnit.MINUTES.toMillis(minutes);
long seconds = TimeUnit.MILLISECONDS.toSeconds(millis);
return String.format(Locale.ENGLISH, "%02d:%02d:%02d", hours, minutes, seconds);
//return "${getWithLeadZero(hours)}:${getWithLeadZero(minutes)}:${getWithLeadZero(seconds)}"
}
}
如果你已经有了时间。
public class Timer {
private float lastFrameChanged;
private float frameDuration;
private Runnable r;
public Timer(float frameDuration, Runnable r) {
this.frameDuration = frameDuration;
this.lastFrameChanged = 0;
this.r = r;
}
public void update(float dt) {
lastFrameChanged += dt;
if (lastFrameChanged > frameDuration) {
lastFrameChanged = 0;
r.run();
}
}
}