先来个效果图让大家看一看,现在好多app都用类似的注册页

实现思路
用一个透明的EditText与四个TextView重叠,并给TextView设置默认背景
第4个TextView输入完成后,要设置回调,并且要加入增加删除的回调
还要监听EditText内容的变化,获取内容,并且改变EditText下面的TextView的颜色
重新发送的是采用一个自定义的CountDownTimer类
弹出效果自定义的一个Dialog继承DialogFragment

自定义EditText的布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="47dp"android:gravity="center"android:orientation="horizontal"android:weightSum="3"><TextViewandroid:id="@+id/item_code_iv1"style="@style/text_editStyle" /><Viewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1" /><TextViewandroid:id="@+id/item_code_iv2"style="@style/text_editStyle" /><Viewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1" /><TextViewandroid:id="@+id/item_code_iv3"style="@style/text_editStyle" /><Viewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1" /><TextViewandroid:id="@+id/item_code_iv4"style="@style/text_editStyle" /></LinearLayout><EditTextandroid:id="@+id/item_edittext"android:layout_width="match_parent"android:layout_height="47dp"android:background="@android:color/transparent"android:inputType="number" />
</RelativeLayout>

style

 <style name="text_editStyle" ><item name="android:layout_height">47dp</item><item name="android:layout_width">47dp</item><item name="android:background">@mipmap/bg_verify</item><item name="android:gravity">center</item><item name="android:textColor">@color/common_blue_0090FF</item><item name="android:textSize">18sp</item></style>

View的代码

 private EditText editText;private TextView[] TextViews;private StringBuffer stringBuffer = new StringBuffer();private int count = 4;private String inputContent;public SecurityCodeView(Context context) {this(context, null);}public SecurityCodeView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public SecurityCodeView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);TextViews = new TextView[4];View.inflate(context, R.layout.view_security_code, this);editText = (EditText) findViewById(R.id.item_edittext);TextViews[0] = (TextView) findViewById(R.id.item_code_iv1);TextViews[1] = (TextView) findViewById(R.id.item_code_iv2);TextViews[2] = (TextView) findViewById(R.id.item_code_iv3);TextViews[3] = (TextView) findViewById(R.id.item_code_iv4);editText.setCursorVisible(false);//将光标隐藏setListener();}/*** 清空输入内容*/public void clearEditText() {stringBuffer.delete(0, stringBuffer.length());inputContent = stringBuffer.toString();for (int i = 0; i < TextViews.length; i++) {TextViews[i].setText("");TextViews[i].setBackgroundResource(R.mipmap.bg_verify);}}private InputCompleteListener inputCompleteListener;public void setInputCompleteListener(InputCompleteListener inputCompleteListener) {this.inputCompleteListener = inputCompleteListener;}public interface InputCompleteListener {void inputComplete();void deleteContent(boolean isDelete);}/*** 获取输入文本** @return*/public String getEditContent() {return inputContent;}

监听代码

 private void setListener() {editText.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}@Overridepublic void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}@Overridepublic void afterTextChanged(Editable editable) {//重点   如果字符不为""时才进行操作if (!editable.toString().equals("")) {if (stringBuffer.length() > 3) {//当文本长度大于3位时edittext置空editText.setText("");return;} else {//将文字添加到StringBuffer中stringBuffer.append(editable);editText.setText("");//添加后将EditText置空  造成没有文字输入的错局//  Log.e("TAG", "afterTextChanged: stringBuffer is " + stringBuffer);count = stringBuffer.length();//记录stringbuffer的长度inputContent = stringBuffer.toString();if (stringBuffer.length() == 4) {//文字长度位4  则调用完成输入的监听if (inputCompleteListener != null) {inputCompleteListener.inputComplete();}}}for (int i = 0; i < stringBuffer.length(); i++) {TextViews[i].setText(String.valueOf(inputContent.charAt(i)));TextViews[i].setBackgroundResource(R.mipmap.bg_verify_press);}}}});editText.setOnKeyListener(new OnKeyListener() {@Overridepublic boolean onKey(View v, int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_DEL&& event.getAction() == KeyEvent.ACTION_DOWN) {if (onKeyDelete()) return true;return true;}return false;}});}public boolean onKeyDelete() {if (count == 0) {count = 4;return true;}if (stringBuffer.length() > 0) {//删除相应位置的字符stringBuffer.delete((count - 1), count);count--;//   Log.e(TAG, "afterTextChanged: stringBuffer is " + stringBuffer);inputContent = stringBuffer.toString();TextViews[stringBuffer.length()].setText("");TextViews[stringBuffer.length()].setBackgroundResource(R.mipmap.bg_verify);if (inputCompleteListener != null)inputCompleteListener.deleteContent(true);//有删除就通知manger}return false;}

自定义的EditText到这了算是结束了

弹出框的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/activity_main"android:layout_width="283dp"android:layout_height="273dp"android:layout_gravity="center"android:layout_marginBottom="50dp"android:background="@mipmap/bg_view1"android:orientation="vertical"><include layout="@layout/layout_titile" /><com.example.admin.myapplication.SecurityCodeViewandroid:id="@+id/scv_edittext"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:layout_marginLeft="20dp"android:layout_marginRight="20dp"android:layout_marginTop="35dp" /><TextViewandroid:id="@+id/tv_text"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="20dp"android:layout_marginRight="20dp"android:layout_marginTop="13dp"android:text="输入验证码表示同意《用户协议》" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="25dp"android:layout_marginTop="3dp"android:orientation="horizontal"><TextViewandroid:id="@+id/tv_phone"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_marginLeft="20dp"android:layout_marginRight="20dp"android:layout_marginTop="13dp"android:layout_weight="1"android:text="电话" /><TextViewandroid:id="@+id/tv_click"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="20dp"android:layout_marginRight="20dp"android:layout_marginTop="13dp"android:text="重新发送"android:textColor="@color/colorPrimary" /></LinearLayout></LinearLayout>

[大体的思路,点击事件之后弹出一个Dialog,然后再这个页面进行注册,有可能这个Dialog会复用,或者改一些样式(采用Builder设计模式)]

接下来自定义Dialog

要实现EditText的两个接口

public class XyAlertDialog extends DialogFragment implements SecurityCodeView.InputCompleteListener {private SecurityCodeView editText;private TextView text;private TextView tv_title;private ImageView img_close;public static final String TAG = XyAlertDialog.class.getSimpleName();private Builder builder;private static XyAlertDialog instance = new XyAlertDialog();private TextView tv_phone;private TextView tv_click;public static XyAlertDialog getInstance() {return instance;}@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {this.setCancelable(true);setRetainInstance(true);super.onCreate(savedInstanceState);if (savedInstanceState != null) {try {if (isAdded() && getActivity() != null)if (builder != null)builder = (Builder) savedInstanceState.getSerializable(Builder.class.getSimpleName());} catch (Exception e) {}}}@Overridepublic void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);try {if (isAdded() && getActivity() != null)if (builder != null)outState.putSerializable(Builder.class.getSimpleName(), builder);} catch (Exception e) {Log.d(TAG, e.toString());}}@NonNull@Overridepublic Dialog onCreateDialog(Bundle savedInstanceState) {Dialog dialog = super.onCreateDialog(savedInstanceState);dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);dialog.setCanceledOnTouchOutside(false);//点击旁白不消失return dialog;}@Nullable@Overridepublic View onCreateView(LayoutInflater inflater, @Nullable ViewGroupcontainer, @Nullable Bundle savedInstanceState) {return inflater.inflate(R.layout.activity_xia, container, false);}@Overridepublic void onViewCreated(View view, @Nullable Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);initViews(view);}private Dialog show(Activity activity, Builder builder) {this.builder = builder;if (!isAdded())show(((AppCompatActivity) activity).getSupportFragmentManager(), TAG);return getDialog();}private void initViews(View view) {tv_title = (TextView) view.findViewById(R.id.tv_title);img_close = (ImageView) view.findViewById(R.id.img_close);editText = (SecurityCodeView) view.findViewById(R.id.scv_edittext);text = (TextView) view.findViewById(R.id.tv_text);tv_phone = (TextView) view.findViewById(R.id.tv_phone);tv_click = (TextView) view.findViewById(R.id.tv_click);editText.setInputCompleteListener(this);tv_phone.setText(builder.getTextTitle());img_close.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {dismiss();}});tv_click.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {CountDownTimerUtils mCountDownTimerUtils = new CountDownTimerUtils(tv_click, 60000, 1000);mCountDownTimerUtils.start();}});}public static class Builder implements Serializable {private String positiveButtonText;private String negativeButtonText;private String textTitle;private String body;private OnPositiveClicked onPositiveClicked;private OnNegativeClicked onNegativeClicked;private boolean autoHide;private int timeToHide;private int positiveTextColor;private int backgroundColor;private int negativeColor;private int titleColor;private int bodyColor;private Typeface titleFont;private Typeface bodyFont;private Typeface positiveButtonFont;private Typeface negativeButtonFont;private Typeface alertFont;private Context context;private PanelGravity buttonsGravity;public PanelGravity getButtonsGravity() {return buttonsGravity;}public Builder setButtonsGravity(PanelGravity buttonsGravity) {this.buttonsGravity = buttonsGravity;return this;}public Typeface getAlertFont() {return alertFont;}public Builder setAlertFont(String alertFont) {this.alertFont = Typeface.createFromAsset(context.getAssets(), alertFont);return this;}public Typeface getPositiveButtonFont() {return positiveButtonFont;}public Builder setPositiveButtonFont(String positiveButtonFont) {this.positiveButtonFont = Typeface.createFromAsset(context.getAssets(), positiveButtonFont);return this;}public Typeface getNegativeButtonFont() {return negativeButtonFont;}public Builder setNegativeButtonFont(String negativeButtonFont) {this.negativeButtonFont = Typeface.createFromAsset(context.getAssets(), negativeButtonFont);return this;}public Typeface getTitleFont() {return titleFont;}public Builder setTitleFont(String titleFontPath) {this.titleFont = Typeface.createFromAsset(context.getAssets(), titleFontPath);return this;}public Typeface getBodyFont() {return bodyFont;}public Builder setBodyFont(String bodyFontPath) {this.bodyFont = Typeface.createFromAsset(context.getAssets(), bodyFontPath);return this;}public int getTimeToHide() {return timeToHide;}public Builder setTimeToHide(int timeToHide) {this.timeToHide = timeToHide;return this;}public boolean isAutoHide() {return autoHide;}public Builder setAutoHide(boolean autoHide) {this.autoHide = autoHide;return this;}public Context getContext() {return context;}public Builder setActivity(Context context) {this.context = context;return this;}public Builder(Context context) {this.context = context;}public void setCancelable(boolean flag) {throw new RuntimeException("Stub!");}public int getPositiveTextColor() {return positiveTextColor;}public Builder setPositiveColor(int positiveTextColor) {this.positiveTextColor = positiveTextColor;return this;}public int getBackgroundColor() {return backgroundColor;}public Builder setBackgroundColor(int backgroundColor) {this.backgroundColor = backgroundColor;return this;}public int getNegativeColor() {return negativeColor;}public Builder setNegativeColor(int negativeColor) {this.negativeColor = negativeColor;return this;}public int getTitleColor() {return titleColor;}public Builder setTitleColor(int titleColor) {this.titleColor = titleColor;return this;}public int getBodyColor() {return bodyColor;}public Builder setBodyColor(int bodyColor) {this.bodyColor = bodyColor;return this;}public String getPositiveButtonText() {return positiveButtonText;}public Builder setPositiveButtonText(int positiveButtonText) {this.positiveButtonText = context.getString(positiveButtonText);return this;}public Builder setPositiveButtonText(String positiveButtonText) {this.positiveButtonText = positiveButtonText;return this;}public String getNegativeButtonText() {return negativeButtonText;}public Builder setNegativeButtonText(String negativeButtonText) {this.negativeButtonText = negativeButtonText;return this;}public Builder setNegativeButtonText(int negativeButtonText) {this.negativeButtonText = context.getString(negativeButtonText);return this;}public String getTextTitle() {return textTitle;}public Builder setTextTitle(String textTitle) {this.textTitle = textTitle;return this;}public Builder setTextTitle(int textTitle) {this.textTitle = context.getString(textTitle);return this;}public String getBody() {return body;}public Builder setBody(String body) {this.body = body;return this;}public Builder setBody(int body) {this.body = context.getString(body);return this;}public OnPositiveClicked getOnPositiveClicked() {return onPositiveClicked;}public Builder setOnPositiveClicked(OnPositiveClicked onPositiveClicked) {this.onPositiveClicked = onPositiveClicked;return this;}public OnNegativeClicked getOnNegativeClicked() {return onNegativeClicked;}public Builder setOnNegativeClicked(OnNegativeClicked onNegativeClicked) {this.onNegativeClicked = onNegativeClicked;return this;}public Builder build() {return this;}public Dialog show() {return XyAlertDialog.getInstance().show(((Activity) context), this);}}@Overridepublic void onPause() {if (isAdded() && getActivity() != null) {builder = null;}super.onPause();}public interface OnPositiveClicked {void OnClick(View view, Dialog dialog);}public interface OnNegativeClicked {void OnClick(View view, Dialog dialog);}public enum PanelGravity {LEFT,RIGHT,CENTER}
//EditText的接口@Overridepublic void inputComplete() {if (!editText.getEditContent().equals("1234")) {text.setText("验证码输入错误");text.setTextColor(Color.RED);}}@Overridepublic void deleteContent(boolean isDelete) {if (isDelete) {text.setText("输入验证码表示同意《用户协议》");text.setTextColor(Color.BLACK);}}
}

至于那个自定义的CountDownTimer在这里有介绍
http://blog.csdn.net/MacaoPark/article/details/71379520

源码地址
http://download.csdn.net/detail/macaopark/9803228

▲ Android自定义方框EditText注册验证码相关推荐

  1. android方框验证码,Android自定义方框EditText注册验证码

    先来个效果图让大家看一看,现在好多app都用类似的注册页 实现思路 用一个透明的EditText与四个TextView重叠,并给TextView设置默认背景 第4个TextView输入完成后,要设置回 ...

  2. Android 自定义View之随机数验证码(仿写鸿洋)

    前言 本文面向自定义view新手,但是希望你最好有一定的理论知识,或基础概念,有的地方可能会一笔带过并不会细讲,细讲篇幅就太长了. 本文仿写自鸿洋的自定义View (一),尽管过去了将近快7年之久,我 ...

  3. Android自定义View实现滴滴验证码输入框效果

    先上效果图让大家看看 1.VerficationCodeInput.Java /** * 輸入验证码的自定义view * */ public class VerificationCodeInput e ...

  4. android 随机验证码,Android自定义View实现随机验证码

    对于android开发来说自定义View还是一个比较重要的技能,所以在这里写一篇自定义View入门的文章,也是实现一个相对简单的随机产生验证码的功能: 自定义View主要也就分为几步 1.自定义Vie ...

  5. android-短信验证功能,Android实现获取短信验证码的功能以及自定义GUI短信验证详解...

    <Android实现获取短信验证码的功能以及自定义GUI短信验证详解>由会员分享,可在线阅读,更多相关<Android实现获取短信验证码的功能以及自定义GUI短信验证详解(8页珍藏版 ...

  6. android+自定义发彩信,Android实现获取短信验证码的功能以及自定义GUI短信验证

    短信验证功能大家都很熟悉了.在很多地方都能见到,注册新用户或者短息验证支付等.短信验证利用短信验证码来注册会员,大大降低了非法注册,很大程度上提高了用户账户的安全性. 目前市面上已经有了很多提供短信验 ...

  7. Android自定义组合控件--EditText和Button组合成带有清空EditText内容功能的复合控件

    目标:实现EditText和Button组合成带有清空EditText内容功能的复合控件,可以通过代码设置自定义控件的相关属性. 实现效果为: (1)在res/layout目录下编写自定义组合控件的布 ...

  8. android 自定义本地验证码demo,Android 自定义验证码输入框的实例代码(支持粘贴连续性)...

    需求 1.能自定义输入框个数和样式 2.支持长按粘贴或剪切板内容自动填充(粘贴连续性) 其中第2点是最为重要的,正是其他人没有这点,逼得自己弄一个 示例 别人的示例: 粘贴居然不支持连续性,只能粘贴第 ...

  9. 自定义android控件EditText 自定义边框 背景

    自定义EditText边框背景: 首先重新定义一个style.在values文件夹下新建一个xml文件: <?xml version="1.0" encoding=" ...

最新文章

  1. 进程间通信 - 剪贴板实现
  2. 计算机会计学ufo报表,ufo报表实验报告(共10篇).doc
  3. hadooprbac_rbac权限管理系统的学习
  4. idea搭建可运行Servlet的Web项目[maven]
  5. jQuery lazyload
  6. java 守护线程 作用_java中守护线程的一些概念和用法
  7. python入门11 元组tuple
  8. k3c最新官改非常稳定了_2020国庆过后玉米价格最新行情走势
  9. 手工查杀威金病毒,完全恢复exe程序
  10. 苹果暗黑模式_DNF手游来了!时间已定;苹果商店首次加入暗黑模式;以上为本期内容...
  11. 数量积、向量积与混合积
  12. oracle导入blob出错,oracle导出blob,clob出错的问题
  13. linux grep命令要查找的内容有双引号
  14. 关于抽烟、戒烟、或者说是收放自如
  15. Jumpserver界面设置及界面功能
  16. linux下flock函数,flock()函数 Unix/Linux
  17. Java多线程面经整理
  18. 邮政局:异地快递7天内没送达可索回运费
  19. Java 8新特性探究(四)深入解析日期和时间-JSR310
  20. 你知道吗?什么是 Responsive JavaScript ?

热门文章

  1. 蛋白质相互作用系列:GN算法
  2. 40本编程开发电子书免费送
  3. AlexNet模型及代码详解
  4. [最新]Myeclipse 10.7.1 激活工具及过程详解 亲测
  5. 2016校招面试题汇总
  6. 自己交社保的人怎么样才知道自己可以退休了?
  7. (11)RabbitMQ的mandatory、immediate和ReturnListener
  8. Livox激光MID-360使用与fast-lio2激光SLAM建图
  9. 一文搞懂│王者游戏中荣耀水晶难抽?探索游戏中的抽奖算法
  10. 标普500指数的恒定市值回测