aLe*_*ner 6 android timer chronometer
我正在为Android 2.2设计一个天文台/倒数计时器应用程序,并希望按一下按钮同时启动计时器和计时器.因此,理想情况下,我想在秒(时间)都记时计和定时器在同一个实例来改变.(即使计时器正在计数,计时器也会倒计时).由于我使用Android提供的计时器和计时器功能,当用户按下"开始"按钮时,我编写了以下代码
private boolean mStartPressedOnce = false;
long mTimeWhenStopped = 0;
Chronometer mChronometer;
MyCounter mCounter;
...
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.StartButton:
// Perform some initialization for the chronometer depending
// on the button press
if (mStartPressedOnce == false) {
mChronometer.setBase(SystemClock.elapsedRealtime());
} else {
mChronometer.setBase(SystemClock.elapsedRealtime() + mTimeWhenStopped);
}
// Perform the initialization for the timer
mCounter = new MyCount(45000, 1000);
// Fire up the chronometer
mChronometer.start();
// Fire up the timer
mCounter.start();
break;
case R.id.ResetButton:
// Reset the chronometer
mChronometer.setBase(SystemClock.elapsedRealtime());
mTimeWhenStopped = 0;
break;
case case R.id.StopButton:
mStartPressedOnce = true;
// Stop the chronometer
mTimeWhenStopped = mChronometer.getBase() - SystemClock.elapsedRealtime();
mChronometer.stop();
break;
}
...
public class MyCounter extends CountDownTimer {
@Override
public MyCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
@Override
public void onFinish() {
// Nothing to do here
}
@Override
public void onTick(long millisUntilFinished) {
long seconds = (long) (millisUntilFinished / 1000);
long minutes = (long) ((millisUntilFinished / 1000) / 60);
long hours = (long) (((millisUntilFinished / 1000) / 60) / 60);
// Do some formatting to make seconds, minutes and hours look pretty
// Update the timer TextView
(TextView) findViewById(R.id.CountDownTimerTextView))
.setText(hours + ":" + minutes + ":" + seconds);
}
}
Run Code Online (Sandbox Code Playgroud)
虽然看起来计时器和计时器上的秒数最初是同步的,但是在很短的时间之后,它们似乎会熄灭,并且两者的第二次更新都会在不同的时间发生.
想知道我能做些什么来解决这个问题.我确实遇到过 - 并阅读了这个帖子
我意识到可能需要进行设计更改,但我不确定需要做什么.
编辑:计时器和计时器的包含类型以及使用天文台计算时间的方法 - 每个jolivier和njzk2的建议
因此,在思考了一段时间并放弃jolivier与我们慷慨分享的建议之后,我意识到存在一个名为 的方法,onChronometerTick每次有计时器滴答时(在本例中为每秒)都会调用该方法。因此,我想到每次调用该方法时从计数器中减去 1000 毫秒,并相应地更新计时器显示。我完全摆脱了Android计时器部分(CountDownTimer)。我认为这是让两个显示器同时更新的好方法。这也是一个定时器的简单实现。
我很高兴地报告,它似乎运作良好。计时器和天文台显示确实同时更新。所以,原来的问题看起来已经有了答案。不幸的是,我在计时器前端遇到了一个相差两个错误,我用一个丑陋的黑客修复了它。我正在发布到目前为止我所拥有的内容。欢迎任何有关如何修复黑客或改进代码的建议。请注意,我对代码进行了注释,以使其易于理解所做的事情。
编辑 bug:我注意到的另一件事是,大约 10 分钟后,计时器和计时器关闭了一秒钟。更准确地说,计时器落后天文钟一秒。尚不清楚为什么会发生这种情况。
private boolean mStartPressedOnce = false;
long mTimeWhenStopped = 0;
Chronometer mChronometer;
long millisUntilFinished = 0;
boolean firstPassOver = false;
int counter = 0;
...
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.StartButton:
// Perform some initialization for the chronometer depending
// on the button press
if (mStartPressedOnce == false) {
mChronometer.setBase(SystemClock.elapsedRealtime());
} else {
mChronometer.setBase(SystemClock.elapsedRealtime() + mTimeWhenStopped);
}
// Fire up the chronometer
mChronometer.start();
break;
case R.id.ResetButton:
// Reset the chronometer
mChronometer.setBase(SystemClock.elapsedRealtime());
mTimeWhenStopped = 0;
break;
case case R.id.StopButton:
mStartPressedOnce = true;
// Stop the chronometer
mTimeWhenStopped = mChronometer.getBase() - SystemClock.elapsedRealtime();
mChronometer.stop();
break;
}
...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.stop_watch);
mChronometer = (Chronometer) findViewById(R.id.StopWatchTextView);
// Initialize the number of milliseconds before the timer expires (
// set the timer) - in this case to 46 seconds
millisUntilFinished = 46000;
// Display how many seconds remain before the timer expires
((TextView) findViewById(R.id.CountDownTimerTextView)).setText(hours
+ ":" + minutes + ":" + millisUntilFinished / 1000);
// In line with the suggestion provided by jolivier - make the timer
// the slave and update its display every time the chronometer
// ticks
mChronometer
.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
@Override
public void onChronometerTick(Chronometer chronometer) {
// Update the display for the chronometer
CharSequence text = chronometer.getText();
chronometer.setText(text);
// Update the display for the timer
// !!! BUG !!!
// Looks like onChronometerTick is called at the 0th second
// and this causes an off by two error if a count down timer
// is being implemented. Fixed it with this hack. There's gotta
// be a more elegant solution, though.
if(counter >= 2) {
millisUntilFinished1 = millisUntilFinished1 - 1000;
counter = 2;
}
counter++;
if (millisUntilFinished >= 0) {
long seconds = (long) (millisUntilFinished / 1000);
long minutes = (long) ((millisUntilFinished / 1000) / 60);
long hours = (long) (((millisUntilFinished / 1000) / 60) / 60);
// Do some formatting to make seconds, minutes and hours look pretty
// Update the timer TextView
((TextView) findViewById(R.id.CountDownTimerTextView))
.setText(hours + ":" + minutes + ":"
+ seconds);
}
}
});
// Other code
...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1234 次 |
| 最近记录: |