Android:旋转后如何恢复停止计时器的状态?

时间:2015-02-04 16:18:53

标签: android chronometer

我正在这样做以保存状态并在计时器运行时在旋转后恢复它。 Android_Chronometer pause

当我在Xsec停止计时器然后在Y秒后停止时,我改变了计时器标记X + Y秒的方向。 无论经过多长时间,我都希望在旋转之前留下停止计时器的时间。我该怎么办?

3 个答案:

答案 0 :(得分:2)

我对Chronometer类以及如何在方向变化中存活时遇到了类似的问题。虽然有几个有用的帖子和例子,但我发现没有解决整个问题。

这是一篇有用的帖子Android_Chronometer pause,这有助于证明需要保存elapsedTime以恢复计时。

然而,这并未讨论如何使计时器在Android生命周期方向上发生变化。在计时器运行与暂停时,您对经过时间的处理略有不同。

这就是我把所有这些放在一起 - 暂停,恢复,重置,在一个好的课堂上,以及幸存的方向:

 public class ChronometerWithPause extends Chronometer {
    private long timeWhenStopped = 0;
    private boolean isRunning = false;

    private final String getTimeKey() {
        return "KEY_TIMER_TIME" + getId();
    }
    private final String getIsRunningKey() {
        return "KEY_TIMER_RUNNING" + getId();
    }

    public ChronometerWithPause(Context context) {
        super(context);
    }

    public ChronometerWithPause(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ChronometerWithPause(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void start() {
        setBase(SystemClock.elapsedRealtime() - timeWhenStopped);
        isRunning = true;
        super.start();
    }

    @Override
    public void stop() {
        isRunning = false;
        timeWhenStopped = SystemClock.elapsedRealtime() - getBase();
        super.stop();
    }

    public void reset() {
        stop();
        isRunning = false;
        setBase(SystemClock.elapsedRealtime());
        timeWhenStopped = 0;
    }

    public boolean isRunning() {
        return isRunning;
    }

    public long getCurrentTime() {
        return timeWhenStopped;
    }

    public void setCurrentTime(long time) {
        timeWhenStopped = time;
        setBase(SystemClock.elapsedRealtime() - timeWhenStopped);
    }

    public void saveInstanceState(Bundle outState) {
        if (isRunning) {
            timeWhenStopped = SystemClock.elapsedRealtime() - getBase();
        }
        outState.putLong(getTimeKey(), getCurrentTime());
        outState.putBoolean(getIsRunningKey(), isRunning());
    }

    public void restoreInstanceState(Bundle inState) {
        isRunning = inState.getBoolean(getIsRunningKey());
        setCurrentTime(inState.getLong(getTimeKey()));
        timeWhenStopped = SystemClock.elapsedRealtime() - getBase();
        if (isRunning) {
            super.start();
        }
    }
}

请注意,您可以在onSaveInstanceState()onCreate()中使用此功能:

protected void onSaveInstanceState(Bundle outState) {
           ...
           timer.saveInstanceState(outState);
           ...

然后在onCreate中,您可以使用以下命令恢复计时器功能:

if (savedInstanceState != null) {
             // . . .
                timer.restoreInstanceState(savedInstanceState);
             // . . .
}

答案 1 :(得分:0)

如果您使用的是轻微的解决方案,您还可以执行以下操作:将ChronometerInstance.getText()的值保存到Bundle,然后使用ChronometerInstance.setText()重新设置。它不是很友好,但它有效并且不涉及计算偏移量并存储long值,直到您确实需要它们为止。

它也完全混淆了重新启动天文台的能力,但是由于恢复计时器在恢复时表现出意外(继续使用相同的底座,所以它会跳到任何时候它会发生的事情。'在我看来,这并不是太大的损失。

但是,如果您需要旧的基准时间,请使用comments of the other solution中的解决方案:保存

的值
long diff = SystemClock.elapsedRealtime() - chronometerInstance.getBase();

然后,当您想要恢复它时,请设置

ChronometerInstance.setBase(SystemClick.elapsedRealtime() - diff);

如果之后没有显示该值,您可能需要强制重新绘制。最简单的方法可能只是做一个

ChronometerInstance.start();
ChronometerInstance.stop();

(因为我不知道.invalidate()是否可以做到这一点)

答案 2 :(得分:-1)

感谢评论中的澄清。

要解决您的问题,您可以轻松保存

onSaveInstanceState()

与您的天文台的当前状态相关的变量,然后在onCreate或

中检索它
onRestoreInstanceState()

(第二种方法更好)并相应地设置你的计时器状态。

编辑:从计时器调用中检索已用时间:

SystemClock.elapsedRealtime() - chronometerInstance.getBase();