本文实例为大家分享了Chronometer实现倒计时功能,AndroID提供了实现按照秒计时的API,供大家参考,具体内容如下
一、自定义ChronometerVIEw 继续自TextVIEw
主要原理:先设置一个基准倒计时时间mBaseSeconds,内置handler 每隔1s发送一个空消息,mRemainSeconds--,同时刷新界面视图,回调给外部调用者,只到为零。外部调用者可通过start()/pause()/stop()来控制计时器的工作状态。
可以app中发送短信验证码的场景为例,做了一个很粗糙的界面,但功能都实现了。
/** * @name 倒计时器(类似妙表倒数计时,支持暂停、停止、重新开始) * @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,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(); } } /** * 停止计时器,再次调用 start()重新启动 */ public voID stop() { mStarted = false; mReStart = true; updateStatus(); updateText(mRemainSeconds = 0); dispatchTickListener(); } /** * 刷新内部状态 */ 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); } /** * 在未启动状态下设置开始倒计时时间 * * @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中做一个简单的测试(可以发送短信验证码的实际应用场景为例)
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("重新发送"); } } }); mChronometerVIEw.setText("点击发送验证码"); } 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; } } }; }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的Android自定义Chronometer实现短信验证码秒表倒计时功能全部内容,希望文章能够帮你解决Android自定义Chronometer实现短信验证码秒表倒计时功能所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)