Android Chronometer控件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chennai1101/article/details/84029935

相关文章
Android Picker控件
Android Clock控件
Android Chronometer控件
Android Handler类
Java Formatter类

1. Chronometer类

Chronometer是一个简单的计时器。

主要配置

  • format,显示格式,默认是"MM:SS"或"H:MM:SS",以%s来格式化。
  • countDown,是否倒计时,与base时间相比较

主要方法

  • start,开始计时
  • stop,停止计时
  • setBase,设置计时基准时间
  • setFormat,设置显示格式
  • setCountDown,设置是否是倒计时,只有版本大于24才有效
  • setOnChronometerTickListener,设置监听器

实例代码

mChronometer.setBase(SystemClock.elapsedRealtime());
mChronometer.setFormat("计时开始 %s");
mChronometer.start();

效果如下
在这里插入图片描述

2. Chronometer代码分析

startstop修改了mStarted的状态,然后调用updateRunning。Chronometer状态由三部分组成,mVisible(Window是否可见)、mStarted(Chronometer开始计时)和isShown(View是否可见)。如果状态变化,修改当前控件。updateText修改界面,dispatchChronometerTick触发监听事件。postDelayed在一秒后修改界面。

public void start() {
    mStarted = true;
    updateRunning();
}

public void stop() {
    mStarted = false;
    updateRunning();
}

private void updateRunning() {
    boolean running = mVisible && mStarted && isShown();
    if (running != mRunning) {
        if (running) {
            updateText(SystemClock.elapsedRealtime());
            dispatchChronometerTick();
            postDelayed(mTickRunnable, 1000);
        } else {
            removeCallbacks(mTickRunnable);
        }
        mRunning = running;
    }
}

private final Runnable mTickRunnable = new Runnable() {
    @Override
    public void run() {
        if (mRunning) {
            updateText(SystemClock.elapsedRealtime());
            dispatchChronometerTick();
            postDelayed(mTickRunnable, 1000);
        }
    }
};

updateText修改当前界面,首先拿当前时间和mBase时间作比较,second是两种之间的差值。DateUtilssecond格式化,一般是"MM:SS"或"H:MM:SS",输出text。如果定义了format格式,利用Formattertext进一步格式化。

private synchronized void updateText(long now) {
    mNow = now;
    long seconds = mCountDown ? mBase - now : now - mBase;
    seconds /= 1000;
    boolean negative = false;
    if (seconds < 0) {
        seconds = -seconds;
        negative = true;
    }
    String text = DateUtils.formatElapsedTime(mRecycle, seconds);
    if (negative) {
        text = getResources().getString(R.string.negative_duration, text);
    }

    if (mFormat != null) {
        Locale loc = Locale.getDefault();
        if (mFormatter == null || !loc.equals(mFormatterLocale)) {
            mFormatterLocale = loc;
            mFormatter = new Formatter(mFormatBuilder, loc);
        }
        mFormatBuilder.setLength(0);
        mFormatterArgs[0] = text;
        try {
            mFormatter.format(mFormat, mFormatterArgs);
            text = mFormatBuilder.toString();
        } catch (IllegalFormatException ex) {
            if (!mLogged) {
                Log.w(TAG, "Illegal format string: " + mFormat);
                mLogged = true;
            }
        }
    }
    setText(text);
}

dispatchChronometerTick触发监听事件。

void dispatchChronometerTick() {
    if (mOnChronometerTickListener != null) {
        mOnChronometerTickListener.onChronometerTick(this);
    }
}

setFormat设置显示格式

public void setFormat(String format) {
    mFormat = format;
    if (format != null && mFormatBuilder == null) {
        mFormatBuilder = new StringBuilder(format.length() * 2);
    }
}

setBase设置计时基准时间

public void setBase(long base) {
    mBase = base;
    dispatchChronometerTick();
    updateText(SystemClock.elapsedRealtime());
}

猜你喜欢

转载自blog.csdn.net/chennai1101/article/details/84029935