IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android基础到进阶UI 计时器Chronometer 使用+实例 -> 正文阅读

[移动开发]Android基础到进阶UI 计时器Chronometer 使用+实例

Chronometer

????????Chronometer是一个「简单的计时器」组件,继承自TextView。但是Chronometer「不显示当前时间」,它显示的是从某个起始时间开始,一共过去了多长时间。

主要XML属性如下:

  • 「android:countDown」 是否倒计时,默认false。

  • 「android:format」 设置显示时间格式。如果指定,第一个 「"%s"」 替换为"MM:SS"或"H:MM:SS"形式的当前计时器值。

常用方法

  • 「start()」:开始计时

  • 「stop()」:停止计时

  • 「setBase(long)」:设置计时器起始时间。

  • 「setFormat(String)」:设置显示时间格式

  • 「setCountDown(boolean)」:设置是否是倒计时(SDK版本大于23)。

  • 「setOnChronometerTickListener(OnChronometerTickListener)」:为计时器绑定事件监听,当计时器改变时触发该监听器。

示例

看上面介绍十分简单,咱们还是搞个实例了解一下吧,先看效果图。

主界面布局文件

????????仅保留Chronometer相关布局

<?xml?version="1.0"?encoding="utf-8"?>
<LinearLayout?xmlns:android="http://schemas.android.com/apk/res/android"
????android:layout_width="match_parent"
????android:layout_height="match_parent"
????android:orientation="vertical"
????android:padding="@dimen/dimen_20">
????<Chronometer
????????android:id="@+id/chronometer"
????????android:layout_width="wrap_content"
????????android:layout_height="wrap_content"
????????android:textSize="@dimen/dimen_20"
????????android:padding="@dimen/dimen_10"
????????android:layout_gravity="center_horizontal"
????????android:textColor="@color/color_188FFF"?/>
????<Chronometer
????????android:id="@+id/ch_format"
????????android:layout_width="wrap_content"
????????android:layout_height="wrap_content"
????????android:textSize="@dimen/dimen_20"
????????android:padding="@dimen/dimen_10"
????????android:layout_gravity="center_horizontal"
????????android:textColor="@color/color_ff0000"?/>
</LinearLayout>

主界面代码

public?class?ChronometerActivity?extends?AppCompatActivity?implements?View.OnClickListener?{
????private?Button?btn_start,btn_stop,btn_reset,btn_format_1;
????private?Chronometer?chronometer,ch_format;
????@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());
????????????????dispatchChronometerTick();
????????????????postDelayed(mTickRunnable,?1000);
????????????}?else?{
????????????????removeCallbacks(mTickRunnable);
????????????}
????????????mRunning?=?running;
????????}
????}

setFormat(String)

????//默认"MM:SS"或"H:MM:SS"形式
????public?void?setFormat(String?format)?{
????????mFormat?=?format;
????????if?(format?!=?null?&&?mFormatBuilder?==?null)?{
????????????mFormatBuilder?=?new?StringBuilder(format.length()?*?2);
????????}
????}

setCountDown()

public?void?setCountDown(boolean?countDown)?{
????????mCountDown?=?countDown;
????????updateText(SystemClock.elapsedRealtime());
????}

还有updateText()

当你setCountDown(true)时,直接在当前计时数值前加"-"。如:

  • setCountDown(false)显示:计时器:「20」秒,

  • setCountDown(true)显示:计时器:「-20」秒,

以上就是本文的全部内容,希望对大家学习Android ImageView有所帮助和启发。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-07-24 11:36:36  更:2021-07-24 11:36:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/1 23:05:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码