Android自定义TimeButton实现倒计时按钮

项目需要要实现一个带有倒计时功能的按钮,其效果类似发送验证码之后在按钮上显示倒计时并且将按钮设置为不可用的功能。

为了项目中其他地方能够调用到,便重写了一个继承于Button的TimeButton来实现倒计时功能,并方便调用。

老规矩,上效果图:

逻辑也不复杂,直接上代码:

首先新建一个App.class继承于Application

package com.example.xuboyu.myapplication;

/**
 * 用于存放倒计时时间
 * @author bnuzlbs-xuboyu 2017/4/5.
 */
import java.util.Map;

import android.app.Application;

public class App extends Application {
 // 用于存放倒计时时间
 public static Map<String, Long> map;
}

然后编写TimeButton.class继承于Button

package com.example.xuboyu.myapplication;

import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

/**
 * 倒计时按钮
 * @author bnuzlbs-xuboyu 2017/4/5.
 * 注意把该类的onCreate()onDestroy()和activity的onCreate()onDestroy()同步处理
 */
public class TimeButton extends Button implements OnClickListener {
 private long lenght = 60 * 1000;// 倒计时长度,这里给了默认60秒
 private String textafter = "秒后重新获取~";
 private String textbefore = "点击获取验证码~";
 private int colorafter;
 private int colorbefore;
 private final String TIME = "time";
 private final String CTIME = "ctime";
 private OnClickListener mOnclickListener;
 private Timer t;
 private TimerTask tt;
 private long time;
 Map<String, Long> map = new HashMap<String, Long>();

 public TimeButton(Context context) {
 super(context);
 setOnClickListener(this);

 }

 public TimeButton(Context context, AttributeSet attrs) {
 super(context, attrs);
 setOnClickListener(this);
 }

 @SuppressLint("HandlerLeak")
 Handler han = new Handler() {
 public void handleMessage(android.os.Message msg) {
  TimeButton.this.setText(time / 1000 + textafter);
  time -= 1000;
  if (time < 0) {
  TimeButton.this.setEnabled(true);
  TimeButton.this.setText(textbefore);
  clearTimer();
  }
 };
 };

 private void initTimer() {
 time = lenght;
 t = new Timer();
 tt = new TimerTask() {

  @Override
  public void run() {
  Log.e("xuboyu", time / 1000 + "");
  han.sendEmptyMessage(0x01);//十六进制的数字1
  }
 };
 }

 private void clearTimer() {
 if (tt != null) {
  tt.cancel();
  tt = null;
 }
 if (t != null)
  t.cancel();
 t = null;
 }

 @Override
 public void setOnClickListener(OnClickListener l) {
 if (l instanceof TimeButton) {
  super.setOnClickListener(l);
 } else
  this.mOnclickListener = l;
 }

 @Override
 public void onClick(View v) {
 if (mOnclickListener != null)
  mOnclickListener.onClick(v);
 initTimer();
 this.setText(time / 1000 + textafter);
 this.setEnabled(false);
 t.schedule(tt, 0, 1000);
 // t.scheduleAtFixedRate(task, delay, period);
 }

 /**
 * 和activity的onDestroy()方法同步
 */
 public void onDestroy() {
 if (App.map == null)
  App.map = new HashMap<String, Long>();
 App.map.put(TIME, time);
 App.map.put(CTIME, System.currentTimeMillis());
 clearTimer();
 Log.e("xuboyu", "onDestroy");
 }

 /**
 * 和activity的onCreate()方法同步
 */
 public void onCreate(Bundle bundle) {
 Log.e("xuboyu:倒计时相关", App.map + "");
 if (App.map == null)
  return;
 if (App.map.size() <= 0)// 这里表示没有上次未完成的计时
  return;
 long time = System.currentTimeMillis() - App.map.get(CTIME)
  - App.map.get(TIME);
 App.map.clear();
 if (time > 0)
  return;
 else {
  initTimer();
  this.time = Math.abs(time);
  t.schedule(tt, 0, 1000);
  this.setText(time + textafter);
  this.setEnabled(false);
 }
 }

 /** * 设置计时时候显示的文本 */
 public TimeButton setTextAfter(String text1) {
 this.textafter = text1;
 return this;
 }

 /** * 设置点击之前的文本 */
 public TimeButton setTextBefore(String text0) {
 this.textbefore = text0;
 this.setText(textbefore);
 return this;
 }

 /**
 * 设置到计时长度
 * @param lenght
 * 时间 默认毫秒
 * @return
 */
 public TimeButton setLenght(long lenght) {
 this.lenght = lenght;
 return this;
 }
}

最后在MainActivity.class中调用

package com.example.xuboyu.myapplication;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

/**
 * 测试主界面
 * @author bnuzlbs-xuboyu 2017/4/5.
 */
public class MainActivity extends Activity implements OnClickListener {

 private TimeButton v;
 private TimeButton v2;
 private TimeButton v3;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 v = (TimeButton) findViewById(R.id.button1);
 v.onCreate(savedInstanceState);
 v.setTextAfter("秒后重新排队").setTextBefore("点击开始排队").setLenght(15 * 1000);
 v.setOnClickListener(this);

 v2 = (TimeButton) findViewById(R.id.button2);
 v2.onCreate(savedInstanceState);
 v2.setTextAfter("秒后重新验证").setTextBefore("点击发送验证码").setLenght(10 * 1000);
 v2.setOnClickListener(this);

 v3 = (TimeButton) findViewById(R.id.button3);
 v3.onCreate(savedInstanceState);
 v3.setTextAfter("秒后重新倒计时").setTextBefore("点击开始倒计时").setLenght(5 * 1000);
 v3.setOnClickListener(this);
 }

 @Override
 public void onClick(View v) {
 // TODO Auto-generated method stub
 Toast.makeText(MainActivity.this, "这是处理调用者onclicklistnenr",
  Toast.LENGTH_SHORT).show();
 }

 @Override
 protected void onDestroy() {
 // TODO Auto-generated method stub
 v.onDestroy();
 v2.onDestroy();
 super.onDestroy();
 }
}

其中绿色按钮是使用了自定义样式的Button,使用起来也很简单

首先在drawable中新建一个样式文件mybutton.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
 <solid android:color="#5cbe6c" />

 <!-- 设置按钮的四个角为弧形 -->
 <!-- android:radius 弧形的半径 -->
 <corners android:radius="15dip" />

 <!-- padding:Button里面的文字与Button边界的间隔 -->
 <padding
 android:bottom="10dp"
 android:left="10dp"
 android:right="10dp"
 android:top="10dp" />
</shape>

然后在定义TimeButton的时候如下:

android:background="@drawable/mybutton"
<com.example.xuboyu.myapplication.TimeButton
 android:id="@+id/button2"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:text=""
 android:background="@drawable/mybutton"
 android:layout_margin="20dp"/>

那么定义出来的Button样式就为下图:

记得在AndroidManifest.xml中的Application添加:

android:name=".App"
<application
 android:allowBackup="true"
 android:icon="@mipmap/ic_launcher"
 android:label="@string/app_name"
 android:supportsRtl="true"
 android:theme="@style/AppTheme"
 android:name=".App">
 <activity android:name=".MainActivity" >
  <intent-filter>
  <action android:name="android.intent.action.MAIN" />

  <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
 </activity>
</application>

Ps.这个倒计时按钮存在一个问题,对于长时间计时而言,用户可能在计时后退出应用程序,如果用户把我们的APP置于后台,那么OK,我们的倒计时还是可以进行,但是假如用户在退出后把APP进程滑掉,或者使用了其他软件清理后台等等,就会执行OnDestory方法,再次进去APP的时候只能重新建立一个Timer。所以打算的是使用轻量级存储来储存每次退出后的倒计时数据,然后在重新OnCreate的时候为Timer赋值。当然对于短时间的计时,即在用户可接受的等待范围内是完全可以接受的!有Bug也欢迎指出,对于应用进程被销毁时Timer也销毁这个问题假如你有更好的解决方法,也请多指教!

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

(0)

相关推荐

  • Android自定义倒计时按钮

    本文实例为大家分享了Android自定义倒计时按钮的具体代码,供大家参考,具体内容如下 效果 代码: package com.dylan.frame.ui; import android.content.Context; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.view.View; import android.widget.But

  • Android实现倒计时的按钮效果

    最近有人问我如何实现倒计时的按钮功能,例如发送验证码,我记得有个CountDownTimer,因为好久没用过了,自己就写了一个,代码如下 new CountDownTimer(10000, 1000) { @Override public void onTick(long millisUntilFinished) { btn2.setEnabled(false); btn2.setText(String.format("%ds后重新发送验证码",millisUntilFinished/

  • Android自定义View获取注册验证码倒计时按钮

    在Android开发中,我们不可避免的会做到注册功能,而现在的注册大多数都是用手机去注册的,那么注册的时候都会要求用获取验证码的方式去验证,我们接下来就来实战一下自定义获取验证码倒计时按钮: 1.先看效果图 2.我们涉及到的变量 //倒计时时长,可设置 /** * 倒计时时长,默认倒计时时间60秒: */ private long length = 60 * 1000; //在点击按钮之前按钮所显示的文字 /** * 在点击按钮之前按钮所显示的文字,默认是获取验证码 */ private Str

  • Android实现倒计时的按钮的示例代码

    最近有人问我如何实现倒计时的按钮功能,例如发送验证码,我记得有个CountDownTimer,因为好久没用过了,自己就写了一个,代码如下 new CountDownTimer(10000, 1000) { @Override public void onTick(long millisUntilFinished) { btn2.setEnabled(false); btn2.setText(String.format("%ds后重新发送验证码",millisUntilFinished/

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

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

  • Android自定义TimeButton实现倒计时按钮

    项目需要要实现一个带有倒计时功能的按钮,其效果类似发送验证码之后在按钮上显示倒计时并且将按钮设置为不可用的功能. 为了项目中其他地方能够调用到,便重写了一个继承于Button的TimeButton来实现倒计时功能,并方便调用. 老规矩,上效果图: 逻辑也不复杂,直接上代码: 首先新建一个App.class继承于Application package com.example.xuboyu.myapplication; /** * 用于存放倒计时时间 * @author bnuzlbs-xuboyu

  • Android 自定义View之倒计时实例代码

    Android 自定义View之倒计时实例代码 需求: 大多数app在注册的时候,都有一个获取验证码的按钮,点击后,访问接口,最终用户会收到短信验证码.为了不多次写这个获取验证码的接口,下面将它自定义成一个view,方便使用. 分析一下,这是一个TextView,点击的时候变色,不能再点击,同时里面的倒计时开始显示.那么就有了下面的代码 代码: /** * 通过selector选择器来改变背景,其中倒计时运行时为android:state_enabled="true", * 不显示倒计

  • Android自定义实现可滑动按钮

    本文实例为大家分享了Android自定义实现可滑动按钮的具体代码,供大家参考,具体内容如下 实现逻辑 1.创建一个类继承view类,实现里面的onMeasure() onDraw()方法 2.在 onMeasure() 中需要调用setMeasuredDimension(viewWidth,viewheight),用来绘制按钮的位置区域 3.需要加载按钮的背景和滑块资源 并且转化为bitmap对象 4.获取背景图片的宽和高作为自定义控件的宽和高 5.获取滑块的宽度,用来调整按钮的开和关 6.在o

  • Android自定义短信倒计时view流程分析

    倒计时实现有三种方式 而这个自定义view是通过handler实现的.为了保证activity销毁的同时倒计时线程依然进行同时重新创建销毁又不会导致内存泄漏,我使用了handler的弱引用将handler和runnable设置成静态,同时通过一系列变量来销毁关闭线程保存状态,话不多说先看效果图: 下面看源码: import android.content.Context; import android.os.Handler; import android.os.Message; import a

  • Android自定义view实现倒计时控件

    本文实例为大家分享了Android自定义view实现倒计时控件的具体代码,供大家参考,具体内容如下 直接上代码 自定义TextView 文字展示 public class StrokeTextView extends TextView { private TextView borderText = null;///用于描边的TextView private Context mContext; public StrokeTextView(Context context) { super(conte

  • Android自定义View实现遥控器按钮

    本文实例为大家分享了Android自定义View实现遥控器按钮的具体代码,供大家参考,具体内容如下 效果图: 原理: onSizeChanged拿到控件宽高,进行path和region的计算(此处,path和region的坐标值都是以viewWidth/2,viewHeight/2为坐标原点进行计算的) 画布平移,绘制5个path 点击事件,判断是否处于相应的region区域内,进行控件的重绘 点击事件motionEvent的原始坐标(getX和getY),是以viewParent的左上角为坐标

  • Android自定义APP全局悬浮按钮

    原本想通过framelayout实现一个悬浮在其他控件上的按钮,但是觉得很麻烦,需要各个界面都要动态填充.于是想到了悬浮窗,就自定一个ImageView用于显示全局按钮. 一.首先因为悬浮窗式的所以要添加权限,对于SDK>=23的需要动态获取权限,我这边用的是22的 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:

  • Android 详解自定义圆角输入框和按钮的实现流程

    Android-自定义圆角输入框和按钮 我们的征程是星辰大海,而非人间烟尘 自定义圆角输入框 效果 1.在drawable/下面new Drawable Resources File 2.新建shape文件,在里面自定义xml文件样式 代码文件 <!-- res/drawable/button_shape_normal.xml --> <shape xmlns:android="http://schemas.android.com/apk/res/android" a

随机推荐