android自定义验证码倒计时View
2016-03-25 17:35
483 查看
关于自定义View的构造方法里面的参数的含义可以参考:
/article/5087383.html
代码:
倒计时类:
属性设置(attr):
布局文件:
Activity:activity使用了Data Binding的技术,关于这个可以参考文档 :
https://segmentfault.com/a/1190000002876984
代码比较简单,这里不多做介绍,有什么问题,欢迎批评,android小白一枚.
/article/5087383.html
代码:
倒计时类:
public class CountDownBtn extends Button implements View.OnClickListener { private static final String TAG = CountDownBtn.class.getSimpleName(); private String TIP; private Integer TOTALTIME; private int tempTotalTime; private Integer normalBg; private Integer countTimeBg; private Activity activity; private final static String SECOND = "秒"; private Timer timer; private GetGenerateCodeListener listener; private CountDownBtn instance; public CountDownBtn(Context context) { this(context, null); } public CountDownBtn(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CountDownBtn(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs, defStyleAttr); } private void init(Context context, AttributeSet attrs, int defStyleAttr) { instance = this; if(attrs != null) { TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CountDown); if(array.length() > 0) { TIP = array.getString(R.styleable.CountDown_defTip); tempTotalTime = TOTALTIME = array.getInteger(R.styleable.CountDown_totalTime, 0); normalBg = array.getResourceId(R.styleable.CountDown_normalBg, 0); countTimeBg = array.getResourceId(R.styleable.CountDown_countTimeBg, 0); LogUtils.i(TAG, "data " + TIP + " " + tempTotalTime + " " + normalBg + " " + countTimeBg); checkMessage(tempTotalTime, TIP, normalBg, countTimeBg); array.recycle(); } } } public void setActivity(Activity activity) { if (activity == null) { throw new NullPointerException("activity non null "); } this.activity = activity; } private void start() { timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { activity.runOnUiThread(new Runnable() { @Override public void run() { if (TOTALTIME > 0) { CountDownBtn.this.instance.setText((TOTALTIME) + SECOND); TOTALTIME = TOTALTIME - 1; } else { CountDownBtn.this.instance.setBackground(CountDownBtn.this.getResources().getDrawable(normalBg)); CountDownBtn.this.instance.setText(TIP); timer.cancel(); TOTALTIME = tempTotalTime; CountDownBtn.this.instance.setClickable(true); } } }); } }, 0, 1000); } /** *该法是在layout中不设置相关属性,则需要在code里面动态的设置属性 * @param totalTime 倒计时的时间范围 * @param tipId 默认的提示语 * @param normalBgId 刚开始的默认背景.传入对应的Id * @param countTimeBgId 倒计时时的背景颜色.传入对应的ID */ public void setMessage(int totalTime,int tipId,int normalBgId,int countTimeBgId) { tempTotalTime = this.TOTALTIME = totalTime; this.TIP = this.getResources().getString(tipId); normalBg = normalBgId; countTimeBg = countTimeBgId; checkMessage(TOTALTIME, TIP, normalBg, countTimeBg); } /** * 校验数据合法性.(如果数据不合法,则使用默认值). * @param totalTime * @param tip * @param normalBgId * @param countTimeBgId */ private void checkMessage(int totalTime,String tip,int normalBgId,int countTimeBgId) { LogUtils.i(TAG,"checkMessage user count"); if(totalTime <= 0) { tempTotalTime = totalTime = 60; } if(totalTime > 120) { tempTotalTime = totalTime = 120; } if(TextUtils.isEmpty(tip)) { TIP = this.getResources().getString(R.string.btn_generatecode); } if(normalBgId == 0) { normalBg = R.color.colorAccent; //默认背景,可以自己定义 } if(countTimeBgId == 0) { countTimeBg = R.color.colorPrimary; //倒计时背景,可以自己定义 } this.setBackground(getResources().getDrawable(normalBg)); this.setText(TIP); this.setGravity(Gravity.CENTER); this.setOnClickListener(this); } public void cance() { if(timer != null) { timer.cancel(); } } @Override public void onClick(View v) { if(this.getText().equals(TIP)) { this.setClickable(false); this.setBackground(this.getResources().getDrawable(countTimeBg)); start(); if(listener != null) { listener.getGenerateCode(); } } } /** * 单击获取验证码以后的回调,在里面进行获取验证码的各种操作(networker) */ public interface GetGenerateCodeListener { void getGenerateCode(); } public void setGenerateCodeListener(GetGenerateCodeListener listener) { this.listener = listener; } }
属性设置(attr):
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="CountDown"> <!--默认提示语--> <attr name="defTip" format="string"></attr> <!--总计的倒计时时间以秒为单位--> <attr name="totalTime" format="integer"></attr> <!--正常情况下的背景--> <attr name="normalBg" format="reference"></attr> <!--倒计时的背景颜色--> <attr name="countTimeBg" format="reference"></attr> </declare-styleable> </resources>
布局文件:
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="true" android:fitsSystemWindows="true" android:orientation="vertical"> <android.support.v7.widget.Toolbar android:id="@+id/toolBarBossLogin" android:layout_width="fill_parent" android:layout_height="wrap_content"> </android.support.v7.widget.Toolbar> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <android.support.design.widget.TextInputLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"> <AutoCompleteTextView android:id="@+id/tvPhone" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/hint_phonenumber" android:inputType="phone" android:maxLines="1" android:singleLine="true"/> </android.support.design.widget.TextInputLayout> <com.channelsoft.ggsj.view.CountDownBtn android:id="@+id/btnGenerateCode" android:layout_width="90.0dp" android:layout_height="45.0dp" android:layout_weight="0" app:defTip = "@string/btn_generatecode" app:totalTime = "60" app:normalBg = "@android:color/holo_red_dark" app:countTimeBg = "@android:color/white"> </com.channelsoft.ggsj.view.CountDownBtn> </LinearLayout> <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/tvPassword" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/prompt_password" android:imeActionId="@+id/login" android:imeActionLabel="@string/action_sign_in_short" android:imeOptions="actionUnspecified" android:inputType="textPassword" android:maxLines="1" android:singleLine="true"/> </android.support.design.widget.TextInputLayout> <Button android:id="@+id/bntLogin" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/btn_login" /> </LinearLayout> </layout>
Activity:activity使用了Data Binding的技术,关于这个可以参考文档 :
https://segmentfault.com/a/1190000002876984
public class BossLoginActivity extends BaseActivity implements View.OnClickListener,CountDownBtn.GetGenerateCodeListener { private ActivityBossLoginBinding binding ; private GenerateCodeViewModel generateCodeViewModel; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this,R.layout.activity_boss_login); binding.bntLogin.setOnClickListener(this); binding.btnGenerateCode.setActivity(this); binding.btnGenerateCode.setGenerateCodeListener(this); } @Override public void onClick(View v) { switch(v.getId()) { case R.id.bntLogin: if(checkPhoneNumber()) { generateCodeViewModel = new GenerateCodeViewModel(); generateCodeViewModel.getGenerateCode(binding.tvPhone.getText().toString().trim()); } break; case R.id.btnGenerateCode: break; } } @Override public void getGenerateCode() { } @Override protected void onDestroy() { super.onDestroy(); binding.btnGenerateCode.cance(); } private boolean checkPhoneNumber() { return true; } }
代码比较简单,这里不多做介绍,有什么问题,欢迎批评,android小白一枚.
相关文章推荐
- Android入门
- Grpc在Android中的封装及使用
- Android View体系(八)从源码解析View的layout和draw流程
- Android酷炫实用的开源框架
- Android Browser Share Feature
- android蓝牙技术
- Android开机自启动程序
- Android AndFix热补丁动态修复框架使用教程
- Android侧滑
- android框架之XUtils
- Android中的各种加密和MD5摘要
- Android扫描文件
- Android Studio IDE 所遇问题汇总
- android--显式跳转和隐式跳转
- Android实用开发技巧之二:用Serializable方式及Parcelable方式实现Intent传递对象功能
- android之多渠道打包---秒打秒打
- android学习之intent跳转二简单消息回传
- Android 6.0 - 动态权限管理的解决方案
- android提示框
- 解决android studio Gradle警告GBK编码的不可映射字符的问题