有人能给出一个简单的例子,每秒钟更新一个文本框左右?
我想要制作一个飞行的球,并需要每秒计算/更新球的坐标,这就是为什么我需要某种计时器。
我从这里什么也得不到。
有人能给出一个简单的例子,每秒钟更新一个文本框左右?
我想要制作一个飞行的球,并需要每秒计算/更新球的坐标,这就是为什么我需要某种计时器。
我从这里什么也得不到。
当前回答
我认为你可以用Rx方法来做:
timerSubscribe = Observable.interval(1, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
//TODO do your stuff
}
});
然后取消这个:
timerSubscribe.unsubscribe();
接收定时器 http://reactivex.io/documentation/operators/timer.html
其他回答
这里是解决方案,您需要在代码中添加以下类。您可以直接向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)}"
}
}
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
import android.app.Activity;
public class MainActivity extends Activity {
CheckBox optSingleShot;
Button btnStart, btnCancel;
TextView textCounter;
Timer timer;
MyTimerTask myTimerTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
optSingleShot = (CheckBox)findViewById(R.id.singleshot);
btnStart = (Button)findViewById(R.id.start);
btnCancel = (Button)findViewById(R.id.cancel);
textCounter = (TextView)findViewById(R.id.counter);
btnStart.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
if(timer != null){
timer.cancel();
}
//re-schedule timer here
//otherwise, IllegalStateException of
//"TimerTask is scheduled already"
//will be thrown
timer = new Timer();
myTimerTask = new MyTimerTask();
if(optSingleShot.isChecked()){
//singleshot delay 1000 ms
timer.schedule(myTimerTask, 1000);
}else{
//delay 1000ms, repeat in 5000ms
timer.schedule(myTimerTask, 1000, 5000);
}
}});
btnCancel.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
if (timer!=null){
timer.cancel();
timer = null;
}
}
});
}
class MyTimerTask extends TimerTask {
@Override
public void run() {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat =
new SimpleDateFormat("dd:MMMM:yyyy HH:mm:ss a");
final String strDate = simpleDateFormat.format(calendar.getTime());
runOnUiThread(new Runnable(){
@Override
public void run() {
textCounter.setText(strDate);
}});
}
}
}
. xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<CheckBox
android:id="@+id/singleshot"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Single Shot"/>
您需要创建一个线程来处理更新循环,并使用它来更新文本区域。棘手的部分是只有主线程可以修改ui,所以更新循环线程需要通知主线程进行更新。这是使用处理程序完成的。
查看这个链接:http://developer.android.com/guide/topics/ui/dialogs.html# 点击标题为“Example ProgressDialog with a second thread”的部分。这是一个你需要做什么的例子,除了一个进度对话框而不是一个文本框。
他是更简单的解决方案,工作在我的应用程序。
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;
}
}
}
如果你只是想安排一个倒计时,直到将来的某个时间,并在此过程中定期通知,你可以使用从API级别1开始可用的CountDownTimer类。
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
editText.setText("Seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
editText.setText("Done");
}
}.start();