自定义控件

Android 自定义倒计时控件

2019-04-17  本文已影响0人  BigP

需求描述

倒计时功能是安卓app中常见的功能之一。比如发送验证码啊,距离比赛或者直播或者抢购还有xx时间啊等等。。。
既然这是一个常用控件,何不自定义之以复用之呢?那么话不多说,先来看看倒计时的基本效果:


倒计时效果

实现思路

关键代码实现

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

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毫秒。

/**
* 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();
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);

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

源码地址

https://github.com/wx9265661/SmallDemos2

PS

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

上一篇下一篇

猜你喜欢

热点阅读