android 计时 控件,Android 自定义倒计时控件

需求描述

倒计时功能是安卓app中常见的功能之一。比如发送验证码啊,距离比赛或者直播或者抢购还有xx时间啊等等。。。

既然这是一个常用控件,何不自定义之以复用之呢?那么话不多说,先来看看倒计时的基本效果:

4631571629fe

倒计时效果

实现思路

构思结构

百米高楼平地起,边写边改并不是一个合格程序员的行为态度,首先需要构思该如何实现,需要提供哪些接口,关键的技术方案是啥等等,于是,有了如下的结构图:

4631571629fe

类构造

选型:该控件的基本功能是展现文字,所以可以继承TextView来进行相关的定制。

接口和主要技术方案:从类图中我们可以看到,主要是一个倒计时类,各种倒计时状态的监听以及各种属性值设置的接口

CountDownTimer:使用安卓自带的原生计时工具类。

OnCountDownStartListener:计时开始的监听。

OnCountDownTickListener:计时每秒的回调监听。

mShowFormatTime:是否返回格式化后的时间。

。。。

其他的一些接口类就是设置各种属性,看类名应该就能明白他的功能~

关键代码实现

接下来就是最关键的代码实现部分了!首先,定义回调接口类:

public interface OnCountDownStartListener {

void onStart();

}

public interface OnCountDownTickListener {

/**

* 每秒自己刷新textView

*

* @param untilFinished 剩余的时间

* @param showTime 可以直接使用的显示时间

* @param tv 控件

*/

void onTick(long untilFinished, String showTime, CountDownTextView tv);

}

public interface OnCountDownFinishListener {

void onFinish();

}

这些接口都是拱外部类实现,通过回调方式,来进行相关的操作。

整个倒计时控件的核心功能是计时,这里实现了正向计时和倒计时的功能,通过改变传参即可获取不同的结果,以下就是改控件最关键的count()的功能函数,所有的操作都仰仗他了:

/**

* 计时方案

*

* @param time 计时时长

* @param timeUnit 时间单位

* @param isCountDown 是否是倒计时,false正向计时

*/

private void count(final long time, final long offset, final TimeUnit timeUnit, final boolean isCountDown) {

if (mCountDownTimer != null) {

mCountDownTimer.cancel();

mCountDownTimer = null;

}

setEnabled(mClickable);

// 转换成毫秒

final long millisInFuture = timeUnit.toMillis(time) + 500;

// 时间间隔为1s

long interval = TimeUnit.MILLISECONDS.convert(1, timeUnit);

if (offset == 0 && mOnCountDownStartListener != null) {

mOnCountDownStartListener.onStart();

}

if (TextUtils.isEmpty(mCountDownText)) {

mCountDownText = getText().toString();

}

mCountDownTimer = new CountDownTimer(millisInFuture, interval) {

@Override

public void onTick(long millisUntilFinished) {

long count = isCountDown ? millisUntilFinished : (millisInFuture - millisUntilFinished + offset);

long l = timeUnit.convert(count, TimeUnit.MILLISECONDS);

String showTime;

if (mShowFormatTime) {

showTime = generateTime(count, mIsShowCompleteTv);

} else {

showTime = String.valueOf(l);

}

if (mOnCountDownTickListener != null) {

mOnCountDownTickListener.onTick(l, showTime, CountDownTextView.this);

} else {

setText(String.format(mCountDownText, showTime));

}

}

@Override

public void onFinish() {

setEnabled(true);

mCountDownTimer = null;

if (!TextUtils.isEmpty(mNormalText)) {

setText(mNormalText);

}

if (mOnCountDownFinishListener != null) {

mOnCountDownFinishListener.onFinish();

}

}

};

mCountDownTimer.start();

}

从该段代码中可以看出,该函数主要是对原生的计时方法CountDownTimer进行自定义封装,下面进行简单的解释:

创建计时器:

new CountDownTimer(millisInFuture, interval)

第一个参数是需要计时的时间,单位是毫秒;第二个参数是步长,此处为1000毫秒。

重写CountDownTimer的两个抽象类:

/**

* Callback fired on regular interval.

* @param millisUntilFinished The amount of time until finished.

*/

public abstract void onTick(long millisUntilFinished);

/**

* Callback fired when the time is up.

*/

public abstract void onFinish();

调用

该控件使用起来也很方便,首先在xml中进行定义,属性和TextView都相同。

在代码中调用范例如下:

mCountDownTextView.setNormalText("倒计时控件")

.setBeforeIndex(label.length())

.setCountDownClickable(false)

.setIsShowComplete(true)

.setShowFormatTime(true)

.setOnCountDownTickListener(new CountDownTextView.OnCountDownTickListener() {

@Override

public void onTick(long untilFinished, String showTime, CountDownTextView tv) {

tv.setText(CustomerViewUtils.getMixedText(label + showTime, tv.getTimeIndexes(), true));

}

})

.setOnCountDownFinishListener(new CountDownTextView.OnCountDownFinishListener() {

@Override

public void onFinish() {

mCountDownTextView.setText("倒计时结束");

}

});

}

mCountDownTextView.startCountDown(countDowmNumber);

至此,一个完整的计时控件就完成了。谢谢各位能看到这里的看官~

源码地址

PS

我们看到效果中数字和文字是不同大小和颜色并且垂直居中的,这是通过自定义的SpannableString来实现的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值