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

本文实例为大家分享了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, 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;
  }
 }
 };
} 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android 用RxBinding与RxJava2实现短信验证码倒计时功能

    场景:注册账号页面时,我们点击按钮发送验证码,在等待验证码时,界面会有倒计时提示,这此期间按钮不可点击.当倒计时结束时,按钮恢复. 实现与功能都不难,这次用 RxBinding,RxJava2 的方法去实现.并实现了手动.自动停止倒计时,防止多次点击. 功能动态图 要使用 RxBinding.RxJava2 先添加 Gradle 配置: compile 'io.reactivex.rxjava2:rxandroid:2.0.1' compile 'io.reactivex.rxjava2:rxj

  • Android​短信验证码倒计时验证的2种常用方式

    前言 ​本文主要介绍的是短信验证码功能,这里总结了两种常用的方式,可以直接拿来使用. 看图 计时器 说明:这里的及时从10开始,是为了演示的时间不要等太长而修改的. 方法如下 1.第一种方式:Timer /** * Description:自定义Timer * <p> * Created by Mjj on 2016/12/4. */ public class TimeCount extends CountDownTimer { private Button button; //参数依次为总时

  • Android实现发送短信验证码倒计时功能示例

    一.简介: 开发中在用户注册或找回密码之类的功能,经常会遇到获取短信验证码,获取验证码后需要等待1分钟倒计时,这段时间是不能再次发送短信请求的. 效果图: 二.实现步骤: 1.一个关键类:CountDownTimer(Android系统自带的倒计时功能类) public class CountDownTimerUtils extends CountDownTimer { private TextView mTextView; //显示倒计时的文字 /** * @param textView Th

  • Android开发之获取短信验证码后按钮背景变化并且出现倒计时

    目前越来越多的app在注册或是进行对应操作时,要求获取短信验证码,在点击了获取短信验证码的按钮后,就是出现倒计时,比如倒计时120S,在倒计时期间内,按钮背景变化并且出现倒计时,当倒计时结束后,如果你没有获取到验证码,可以再次点击. 代码如下所示: VerCodeTimer mVerCodeTimer=(Button) findViewById(R.id.login_get_ver_code); private class VerCodeTimer extends CountDownTimer

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

    本文实例为大家分享了Chronometer实现倒计时功能,Android提供了实现按照秒计时的API,供大家参考,具体内容如下 一.自定义ChronometerView 继续自TextView 主要原理:先设置一个基准倒计时时间mBaseSeconds,内置handler 每隔1s发送一个空消息,mRemainSeconds--,同时刷新界面视图,回调给外部调用者,只到为零.外部调用者可通过start()/pause()/stop()来控制计时器的工作状态. 可以app中发送短信验证码的场景为例

  • JS实现用户注册时获取短信验证码和倒计时功能

    在用户注册时,通常需要短信验证码,而且为了交互效果,也需要增加倒计时. 效果如下: <div class="user-form"> <form action="{{ path('zm_member_register') }}" method="post"> <div class="form-list"> <label class="register-label"&g

  • Android中用Bmob实现短信验证码功能的方法详解

    这篇文章主要介绍发送验证码和校验验证码的功能,用到一个第三方平台Bmob,那Bmob是什么呢?Bmob可以开发一个云存储的移动应用软件,他提供了大量的标准的API接口,根据需要接入相关服务,开发者可以更加专注于应用的开发,让产品交付更快速,验证码功能就是其中一个. 一.跟其他第三方一样,我们开发之前要做一些准备工作. 1.首先,去官网注册一个帐号:http://www.bmob.cn/: 2.然后就可以创建应用了:具体怎么做Bmob说得很清楚了(官方操作介绍),如果你不想看,我简单说一下:点击右

  • Android获取和读取短信验证码的实现方法

    现如今,验证码在Android的客户端还是非常普遍的.通过手机账号和验证码直接去注册应用账户的信息.很多应用都以这种方式来完成注册.简单的介绍一下吧. Android获取短信验证码还是比较简单的,通过Mob官网提供的ShareSDK,调用其中内部的方法,就可以获取到短信的验证码了.提供一下Mob的官网地址.http://www.mob.com/#/在官网上注册相关的信息之后,下载相关的jar包和.so文件就可以实现获取短信验证码了(2.0之前的版本都需要下载jar包和 .so文件,而现在的2.2

  • Android实现短信验证码自动填写功能

    本实例为大家分享了Android实现短信验证码自动填写功能,供大家参考,具体内容如下 实现思路很简单: 1.在需要输入验证码的Activity代码注册监听短信的广播 2.拦截短信,获取其中的验证码 3.回写到EditText private SmsReciver smsReciver = new SmsReciver(); /** 收到短信Action **/ String ACTION_SMS_RECIVER = "android.provider.Telephony.SMS_RECEIVED

  • Springboot实现阿里云通信短信服务有关短信验证码的发送功能

    前言 短信验证码是通过发送验证码到手机的一种有效的验证码系统.主要用于验证用户手机的合法性及敏感操作的身份验证. 现在市面上的短信服务平台有很多.大家在选择的时候未免会有些不好抉择.本人建议选择短信服务商应遵循以下几点: 服务商知名度高,业务流量大.(这样的平台可信度高) 服务稳定,不能经常宕机.(保证自身业务的流畅运行) 文档全面详细.(没文档怎么玩?) 最近的一个项目中,注册和修改密码时需要用到短信验证码校验手机号的功能.本人也是对比几家后,直接选择阿里云通信的短信服务.(本身项目服务器也是

  • Android自动获取输入短信验证码库AutoVerifyCode详解

    一.简介 Android的短信验证码自动输入库,内嵌自动申请权限,兼容性高,支持多项配置. 短信验证码长度 验证码类型(大写字母.小写字母.大小写字母.数字.数字字母) 短信内容过滤 发送者号码过滤 短信权限回调,失败重新操作等等 消息回调,可自行处理 Github地址: https://github.com/tpnet/AutoVerifyCode 二.使用 2.1 最简单的使用 适用在验证码为数字,而且验证码为4-6位. AutoVerifyCode.getInstance() .with(

  • Android短信验证码自动填充功能

    笔者发现在很多应用中,都有自动获取验证码的功能:点击获取验证码按钮,收到短信,当前应用不需要退出程序就可以获取到短信中的验证码,并自动填充.觉得这种用户体验很赞,无须用户在短信和App之间来回切换,这个功能是如何实现的呢?其实很简单,就是用到了Android中的一个叫ContentObserver的东西,下面手动简单实现一个~~~ 一.开发ContentObserver 主要是用来监听收件箱的内容,一旦有新消息过来,就去监听是否是我想要的那个号码发过来的短信,如果是,就直接用正则表达式截取 /*

  • Android利用CursorLoader实现短信验证码自动填写

    概述 Android上实现短信验证码自动填写,常用的有两种方式.一种是利用BroadCastReceiver,还有一种是监听手机上短信数据库的变化.利用BroadCastReceiver来实现会在一些情况下无效,最常见的就是手机上安装了具有垃圾短信拦截功能的软件的情况下,短信验证码自动填写无效.所以,现在一般会选用监听数据库内容变化的方式来实现短信验证码自动填写. 网上对于利用监听数据库内容变化来实现短信验证码自动填写的文章也很多,主要分为一下步骤: 1. 继承ContentObserver实现

随机推荐

其他