Android實現(xiàn)一個倒計時自定義控件
(一)前言
Android 其實提供了一個倒計時控件叫做CountDownTimer,這個倒計時控件用起來也很簡單,但是要按照我們想要的倒計時樣式去做就比較繁瑣了。比如說我們希望倒計時按照我們想要的樣式展示HH:MM:SS或者是HH-MM-SS等樣式,或者希望如下展示:

要做的工作就會比較繁瑣了,不是說不能實現(xiàn),只是實現(xiàn)起來代價比較大,所以如果我們將其做成一個自定義的view,可以根據(jù)用戶傳進來的樣式去做倒計時樣式的展示(注:本文的代碼未做這些樣式的功能,但是基于本文代碼很容易實現(xiàn)這個功能),下面就一起看看我實現(xiàn)的倒計時自定義控件吧。
(注;本文代碼不可直接使用到項目中,如果需要使用到項目中,還需要對代碼做處理,比如固定時間到顯示寬度,不然顯示時間時會出現(xiàn)跳躍和顯示不全對情況,例如可以測量“00:00:00”的寬度設置個顯示的view,或者讀者可以自己選擇解決的辦法,還有顯示的時候是否需要去掉字體的內(nèi)邊距,這個都需要讀者自己去決定,去掉內(nèi)邊距也簡單,就是TextView的一個方法setIncludeFontPadding(false)就行了)
(二)效果展示

這個倒計時是精確到了毫秒,但也可以根據(jù)自己的需求去修改。很簡單將格式從“HH:MM:SS SSS ”改為“HH:MM:SS”就可以了
(三)實現(xiàn)思路
實現(xiàn)的思路其實很簡單,繼承自一個TextView,參照系統(tǒng)的倒計時控件做一個封裝就可以了。
首先初始化需要倒計時的時間:
public void init(long timeInFuture, long timeInterval){
mTimeInFuture = timeInFuture;
mTimeInterval = timeInterval;
mStopTimeInFuture = SystemClock.elapsedRealtime() + mTimeInFuture;
updateText(mStopTimeInFuture);
}
timeInFuture 表示你要倒計時的一個時間長度,比如說10秒,3天,5天等,timeInterval表示時間間隔,即每次倒計時遞減多少時間,可以是1秒,2秒,3秒…,elapsedRealtime表示獲取從設備boot后經(jīng)歷的時間值,通過他加上我們的時間長度,就可以準備開始倒計時了。
public void start() {
mStarted = true;
updateTimer();
}
當用戶調(diào)用start()函數(shù)時,會調(diào)用updateTimer()函數(shù),這個函數(shù)會執(zhí)行倒計時的邏輯:
private void updateTimer() {
boolean running = mVisible && mStarted && isShown();
if(running != mRunning){
if(running) {
doCountDownTimer();
}else{
removeCallbacks(mTickRunnable);
}
mRunning = running;
}
}
從代碼中可知,只有控件可見并且時mStarted的情況下才會去做倒計時。倒計時的執(zhí)行函數(shù)doCountDownTimer如下:
private void doCountDownTimer() {
final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
if(millisLeft <= 0){
onFinish();
}else{
long lastUpdateTextStart = SystemClock.elapsedRealtime();
updateText(millisLeft);
// take into account updateText() take time to execute
long lastUpdateTextDuration = SystemClock.elapsedRealtime() - lastUpdateTextStart;
long delay;
if(millisLeft < mTimeInterval){
delay = millisLeft - lastUpdateTextDuration;
if(delay < 0) {
delay = 0;
}
} else {
delay = mTimeInterval - lastUpdateTextDuration;
while (delay < 0) {
delay += mTimeInterval;
}
}
postDelayed(mTickRunnable,delay);
}
}
代碼很容易看懂,這個地方需要特別說明的是,咱們的倒計時利用了view的postDelayed方法,lastUpdateTextDuration這個變量值記錄了上一次更新倒計時text所耗費的時間,把這個時間考慮上會讓倒計時更加精確,因為在demo為了演示的需要所以加了兩個按鈕,在秒殺時,這個時間的精確性還是有要求的,如果差異太大的話會影響用戶體驗。
文章開頭說可以讓時間顯示各種樣式,其實就是把時間中的每個字符分離出來,這樣就能單獨的定義樣式了:
private String formatTime(long now) {
String split = " : ";
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss SSS", Locale.CHINA);
String time = sdf.format(now).replace(" ",":");
Log.d(TAG,"zhongxj: " + time);
String[] time_arr = time.split(":");
int hour = Integer.parseInt(time_arr[0]);
Log.d(TAG,"zhongxj: before transform " + hour);
hour-=8;
Log.d(TAG,"zhongxj: " + hour);
if(hour<10){
time_arr[0] = "0"+hour;
}else{
time_arr[0] = "" + hour;
}
return time_arr[0] + split + time_arr[1] + split
+time_arr[2] + split + time_arr[3];
}
需要加樣式就設計好樣式后把分割好的字符填到樣式中就可以了?。?!
倒計時的邏輯其實是參照的系統(tǒng)倒計時的,這里有個自定義控件的小技巧,當我們接到需求時,先不要忙著去百度,因為大公司很多時候設計的控件百度上很難找到的就算找到了可能也不符合要求,還可能會有隱藏的bug,這時可以參照Android系統(tǒng)是如何實現(xiàn)類似的控件的,參照系統(tǒng)的控件做出來的自定義控件,效果和性能會相對好一些。先說這么多,有問題歡迎一起討論。
(三)代碼地址
代碼倉庫使用的是國內(nèi)的gitee,推薦大家使用起來?。。?!
源碼地址
總結(jié)
到此這篇關于Android實現(xiàn)一個倒計時自定義控件的文章就介紹到這了,更多相關Android倒計時控件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Android Studio使用教程(四):Gradle基礎
這篇文章主要介紹了Android Studio使用教程(四):Gradle基礎,本文講解了什么是Gradle、安裝Gradle、Gradle 基本概念等內(nèi)容,需要的朋友可以參考下2015-05-05
uniapp打包Android的apk(原生APP-云打包)及發(fā)布測試全過程
uni-app本地打包apk需要提前做非常多的準備工作,而且可能會勸退一些開發(fā)者,下面這篇文章主要給大家介紹了關于uniapp打包Android的apk(原生APP-云打包)及發(fā)布測試的相關資料,需要的朋友可以參考下2023-02-02
Android?Activity?View加載與繪制流程深入刨析源碼
這篇文章主要介紹了Android?Activity?View的加載與繪制流程源碼分析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-08-08
android實現(xiàn)點擊按鈕切換不同的fragment布局
這篇文章主要為大家詳細介紹了android實現(xiàn)點擊按鈕切換不同的fragment布局,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-12-12
Android實現(xiàn)仿淘寶購物車增加和減少商品數(shù)量功能demo示例
這篇文章主要介紹了Android實現(xiàn)仿淘寶購物車增加和減少商品數(shù)量功能,結(jié)合實例形式分析了Android實現(xiàn)的淘寶購物車商品數(shù)量變換與計算相關技巧,需要的朋友可以參考下2016-07-07

