@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_textview_chronometer);//加载布局文件
initView();
}
private void initView() {
btn_start = findViewById(R.id.btn_start);
btn_stop = findViewById(R.id.btn_stop);
btn_reset = findViewById(R.id.btn_reset);
chronometer = findViewById(R.id.chronometer);
btn_start.setOnClickListener(this);
btn_stop.setOnClickListener(this);
btn_reset.setOnClickListener(this);
chronometer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onChronometerTick(Chronometer chronometer) {
MLog.e(String.valueOf(chronometer.getBase()));
//当前时间-基准时间>20秒
if(SystemClock.elapsedRealtime()-chronometer.getBase()>20*1000)
{
chronometer.setCountDown(true);
}
}
});
btn_format_1 = findViewById(R.id.btn_format_1);
ch_format = findViewById(R.id.ch_format);
btn_format_1.setOnClickListener(this);
ch_format.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
@Override
public void onChronometerTick(Chronometer chronometer) {
//当前时间-基准时间
long time = SystemClock.elapsedRealtime()-chronometer.getBase();
Date d = new Date(time);
SimpleDateFormat sdf = new SimpleDateFormat(“HH:mm:ss”, Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone(“UTC”));
//设置为HH:mm:ss格式
ch_format.setText(sdf.format(d));
}
});
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_start:
//SystemClock.elapsedRealtime(),自启动以来经过的毫秒数。
//设置基准时间
chronometer.setBase(SystemClock.elapsedRealtime());
//true,倒计时
chronometer.setCountDown(false);
chronometer.setFormat(“计时: %s 秒”);
//开始计时
chronometer.start();
break;
case R.id.btn_stop:
//结束计时
chronometer.stop();
//文字显示
ch_format.setText(“00:00”);
break;
case R.id.btn_reset:
//重置基准时间
chronometer.setBase(SystemClock.elapsedRealtime());
break;
case R.id.btn_format_1:
ch_format.setBase(SystemClock.elapsedRealtime());
ch_format.setCountDown(false);
ch_format.start();
break;
}
}
}
Format格式修改
将Format默认的显示格式是00:00(MM:SS),修改为00:00:00(H:MM:SS)的显示格式。
只要Chronometer发生变化,**「onChronometerTick」**都会被触发,所以我们可以在触发后进行处理。得到我们想要显示样式。
ch_format.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
@Override
public void onChronometerTick(Chronometer chronometer) {
//当前时间-基准时间
long time = SystemClock.elapsedRealtime()-chronometer.getBase();
Date d = new Date(time);
SimpleDateFormat sdf = new SimpleDateFormat(“HH:mm:ss”, Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone(“UTC”));
//设置为HH:mm:ss格式
ch_format.setText(sdf.format(d));
}
});
源码分析
setBase()
public void setBase(long base) {
//设置基准时间
mBase = base;
//触发监听事件
dispatchChronometerTick();
//修改当前界面
updateText(SystemClock.elapsedRealtime());
}
dispatchChronometerTick()
//触发监听事件
void dispatchChronometerTick() {
if (mOnChronometerTickListener != null) {
mOnChronometerTickListener.onChronometerTick(this);
}
}
updateText()
「修改当前界面」,首先拿**「当前时间和mBase时间作比较」,second是两种之间的「差值」**。DateUtils把second格式化,一般是"MM:SS"或"H:MM:SS",输出text。
如果定义了format格式,利用Formatter将text进一步格式化。
//修改
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);
}
start()
public void start() {
mStarted = true;
updateRunning();
}
stop()
public void stop() {
mStarted = false;
updateRunning();
}
updateRunning()
「start()」 和**「stop()」** 方法修改了**「mStarted」的状态,然后调用「updateRunning()」。 Chronometer状态由三部分组成,「mVisible」(Window是否可见)、「mStarted」(Chronometer开始计时)和「isShown」**(View是否可见)。
如果状态变化,修改当前控件。
-
updateText(long)修改界面。
-
dispatchChronometerTick()触发监听事件。
-
postDelayed(Runnable, long)在一秒后修改界面。
private void updateRunning() {
boolean running = mVisible && mStarted && isShown();
if (running != mRunning) {
if (running) {
updateText(SystemClock.elapsedRealtime());
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

结尾
最后小编想说:不论以后选择什么方向发展,目前重要的是把Android方面的技术学好,毕竟其实对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
想要拿高薪实现技术提升薪水得到质的飞跃。最快捷的方式,就是有人可以带着你一起分析,这样学习起来最为高效,所以为了大家能够顺利进阶中高级、架构师,我特地为大家准备了一套高手学习的源码和框架视频等精品Android架构师教程,保证你学了以后保证薪资上升一个台阶。
当你有了学习线路,学习哪些内容,也知道以后的路怎么走了,理论看多了总要实践的。
高级UI,自定义View
UI这块知识是现今使用者最多的。当年火爆一时的Android入门培训,学会这小块知识就能随便找到不错的工作了。
不过很显然现在远远不够了,拒绝无休止的CV,亲自去项目实战,读源码,研究原理吧!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!文章来源地址https://www.toymoban.com/news/detail-851478.html
着你一起分析,这样学习起来最为高效,所以为了大家能够顺利进阶中高级、架构师,我特地为大家准备了一套高手学习的源码和框架视频等精品Android架构师教程,保证你学了以后保证薪资上升一个台阶。
当你有了学习线路,学习哪些内容,也知道以后的路怎么走了,理论看多了总要实践的。
[外链图片转存中…(img-8I1s4c6P-1712364550910)]
高级UI,自定义View
UI这块知识是现今使用者最多的。当年火爆一时的Android入门培训,学会这小块知识就能随便找到不错的工作了。
不过很显然现在远远不够了,拒绝无休止的CV,亲自去项目实战,读源码,研究原理吧!
[外链图片转存中…(img-A3vKHKBY-1712364550911)]文章来源:https://www.toymoban.com/news/detail-851478.html
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
到了这里,关于Android 计时器Chronometer 使用及源码分析(1),android音视频框架的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!