Android自定义Chronometer实现短信验证码秒表倒计时功能

网址简介:未填写

更新时间:10个月前

访问次数:99

详细介绍

当手机应用程序安装后初始化时,为了提高用户体验,通常会以倒计时的形式给用户一定的提示,本文是爱站技术频道小编介绍的自定义Chronometer实现短信验证码秒表倒计时功能,一起来看看吧!

一、自定义ChronometerView 继续自TextView

主要原理:先设置一个基准倒计时时间mBaseSeconds,内置handler 每隔1s发送一个空消息,mRemainSeconds--,同时刷新界面视图,回调给外部调用者,只到为零。外部调用者可通过start()/pause()/stop()来控制计时器的工作状态。
可以app中发送短信验证码的场景为例,做了一个很粗糙的界面,但功能都实现了。

Android自定义Chronometer实现短信验证码秒表倒计时功能-第1张图片

  /**    * @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, 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();    }    }       /**    * 停止计时器,再次调用 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实现短信验证码秒表倒计时功能的全部内容,大家学习到了多少呢?爱站技术频道小编每天都会为大家推荐值得大家学习的知识,继续关注我们吧!

请发表您的评论