Android自定義Chronometer實現(xiàn)短信驗證碼秒表倒計時功能
本文實例為大家分享了Chronometer實現(xiàn)倒計時功能,Android提供了實現(xiàn)按照秒計時的API,供大家參考,具體內(nèi)容如下
一、自定義ChronometerView 繼續(xù)自TextView
主要原理:先設(shè)置一個基準(zhǔn)倒計時時間mBaseSeconds,內(nèi)置handler 每隔1s發(fā)送一個空消息,mRemainSeconds--,同時刷新界面視圖,回調(diào)給外部調(diào)用者,只到為零。外部調(diào)用者可通過start()/pause()/stop()來控制計時器的工作狀態(tài)。
可以app中發(fā)送短信驗證碼的場景為例,做了一個很粗糙的界面,但功能都實現(xiàn)了。
/** * @name 倒計時器(類似妙表倒數(shù)計時,支持暫停、停止、重新開始) * @author Fanjb * @date 2015年11月6日 */ public class ChronometerView extends TextView { /** * A callback that notifies when the chronometer has decremented on its own. * * @author Fanjb */ public interface OnTickChangeListener { /** * remain seconds changed * * @param view * @param remainSeconds */ public void onTickChanged(ChronometerView view, long remainSeconds); } private long mBase; private long mRemainSeconds; private boolean mStarted; private boolean mReStart; private boolean mVisible; private boolean mIsEnable; private OnTickChangeListener mTickListener; public ChronometerView(Context context) { this(context, null); } public ChronometerView(Context context, AttributeSet attrs) { super(context, attrs, 0); } public ChronometerView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); updateText(mRemainSeconds); } @Override protected void onWindowVisibilityChanged(int visibility) { super.onWindowVisibilityChanged(visibility); mVisible = visibility == VISIBLE; updateStatus(); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); mVisible = false; updateStatus(); } /** * 啟動計時器 */ public void start() { if (mReStart && !mStarted) { mRemainSeconds = mBase; } mStarted = true; updateStatus(); } /** * 暫停計時器 */ public void pause() { if (mStarted) { mStarted = mReStart = false; updateStatus(); } } /** * 停止計時器,再次調(diào)用 start()重新啟動 */ public void stop() { mStarted = false; mReStart = true; updateStatus(); updateText(mRemainSeconds = 0); dispatchTickListener(); } /** * 刷新內(nèi)部狀態(tài) */ private void updateStatus() { boolean isEnable = mVisible && mStarted; if (mIsEnable != isEnable) { if (isEnable) { mHandler.sendMessage(Message.obtain(mHandler, TICK_WHAT)); } else { mHandler.removeMessages(TICK_WHAT); } mIsEnable = isEnable; } } private static final int TICK_WHAT = 1; private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { if (mRemainSeconds > 0) { updateText(--mRemainSeconds); dispatchTickListener(); sendMessageDelayed(Message.obtain(this, TICK_WHAT), 1000); } } }; private void updateText(long now) { String text = DateUtils.formatElapsedTime(now); setText(text); } /** * 在未啟動狀態(tài)下設(shè)置開始倒計時時間 * * @param baseSeconds */ public void setBaseSeconds(long baseSeconds) { if (baseSeconds > 0 && baseSeconds != mBase && !mStarted) { mBase = mRemainSeconds = baseSeconds; updateText(mRemainSeconds); } } /** * 剩余時間 * * @return */ public long getRemainSeconds() { return mRemainSeconds; } public void setOnTickChangeListener(OnTickChangeListener listener) { mTickListener = listener; } public OnTickChangeListener getTickListener() { return mTickListener; } private void dispatchTickListener() { if (mTickListener != null) { mTickListener.onTickChanged(this, getRemainSeconds()); } } @Override public void onInitializeAccessibilityEvent(AccessibilityEvent event) { super.onInitializeAccessibilityEvent(event); event.setClassName(ChronometerView.class.getName()); } @Override public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); info.setClassName(Chronometer.class.getName()); } }
二、xml 中沒有加入自定義的控件屬性,同TextView
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <com.freedoman.widgets.calendar.ChronometerView android:id="@+id/chronometer_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:background="@drawable/chronometer_view_bg" android:enabled="true" android:text="00:00" /> <Button android:id="@+id/start_chronometer_view_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:text="Start" /> <Button android:id="@+id/pause_chronometer_view_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:text="Pause" /> <Button android:id="@+id/stop_chronometer_view_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:text="Stop" /> </LinearLayout>
三、在Activity中做一個簡單的測試(可以發(fā)送短信驗證碼的實際應(yīng)用場景為例)
public class ChronometerActivity extends Activity { private ChronometerView mChronometerView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_clock); // 自定義計時器 if (mChronometerView == null) { mChronometerView = (ChronometerView) findViewById(R.id.chronometer_view); mChronometerView.setBaseSeconds(60); mChronometerView.setOnTickChangeListener(new OnTickChangeListener() { @Override public void onTickChanged(ChronometerView view, long curTimeMills) { System.out.println(curTimeMills); view.setEnabled(curTimeMills == 0 || curTimeMills == 60); if (curTimeMills == 0) { mChronometerView.setText("重新發(fā)送"); } } }); mChronometerView.setText("點擊發(fā)送驗證碼"); } findViewById(R.id.start_chronometer_view_btn).setOnClickListener(mClickListener); findViewById(R.id.pause_chronometer_view_btn).setOnClickListener(mClickListener); findViewById(R.id.stop_chronometer_view_btn).setOnClickListener(mClickListener); } private View.OnClickListener mClickListener = new OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.start_chronometer_view_btn: if (mChronometerView != null) { mChronometerView.start(); } break; case R.id.pause_chronometer_view_btn: if (mChronometerView != null) { mChronometerView.pause(); } break; case R.id.stop_chronometer_view_btn: if (mChronometerView != null) { mChronometerView.stop(); } break; } } }; }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- OpenHarmony實現(xiàn)類Android短信驗證碼及倒計時流程詳解
- Android自定義短信倒計時view流程分析
- Android使用CountDownTimer模擬短信驗證倒計時
- Android使用Kotlin和RxJava 2.×實現(xiàn)短信驗證碼倒計時效果
- Android 用RxBinding與RxJava2實現(xiàn)短信驗證碼倒計時功能
- Android實現(xiàn)發(fā)送短信驗證碼倒計時功能示例
- Android短信驗證碼倒計時驗證的2種常用方式
- Android開發(fā)之獲取短信驗證碼后按鈕背景變化并且出現(xiàn)倒計時
- Android封裝實現(xiàn)短信驗證碼的獲取倒計時
相關(guān)文章
Android仿微信進(jìn)度彈出框的實現(xiàn)方法
最近公司項目需要實現(xiàn)類似微信進(jìn)度條彈出框效果,其實現(xiàn)方法并不難,下面給大家介紹下Android仿微信進(jìn)度彈出框的實現(xiàn)方法,需要的朋友參考下吧2017-01-01Android 開發(fā)中根據(jù)搜索內(nèi)容實現(xiàn)TextView中的文字部分加粗
最近遇到一個需求,需要做一個搜索功能。搜索的內(nèi)容需要加粗顯示。實現(xiàn)方法很簡單,下面通過本文給大家分享Android 開發(fā)中根據(jù)搜索內(nèi)容實現(xiàn)TextView中的文字部分加粗樣式,非常不錯,需要的朋友參考下2017-03-03android里TextView加下劃線的幾種方法總結(jié)
下面小編就為大家?guī)硪黄猘ndroid里TextView加下劃線的幾種方法總結(jié)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-10-10