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

实现思路

用一个透明的EditText与四个TextView重叠,并给TextView设置默认背景

第4个TextView输入完成后,要设置回调,并且要加入增加删除的回调

还要监听EditText内容的变化,获取内容,并且改变EditText下面的TextView的颜色

重新发送的是采用一个自定义的CountDownTimer类

弹出效果自定义的一个Dialog继承DialogFragment

自定义EditText的布局

android:layout_width="match_parent"

android:layout_height="wrap_content">

android:layout_width="wrap_content"

android:layout_height="47dp"

android:gravity="center"

android:orientation="horizontal"

android:weightSum="3">

android:id="@+id/item_code_iv1"

style="@style/text_editStyle" />

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1" />

android:id="@+id/item_code_iv2"

style="@style/text_editStyle" />

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1" />

android:id="@+id/item_code_iv3"

style="@style/text_editStyle" />

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1" />

android:id="@+id/item_code_iv4"

style="@style/text_editStyle" />

android:id="@+id/item_edittext"

android:layout_width="match_parent"

android:layout_height="47dp"

android:background="@android:color/transparent"

android:inputType="number" />

style

47dp

47dp

@mipmap/bg_verify

center

@color/common_blue_0090FF

18sp

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() {

@Override

public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

}

@Override

public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

}

@Override

public 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() {

@Override

public 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到这了算是结束了

弹出框的布局

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">

android: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" />

android: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="输入验证码表示同意《用户协议》" />

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_marginBottom="25dp"

android:layout_marginTop="3dp"

android:orientation="horizontal">

android: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="电话" />

android: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" />

[大体的思路,点击事件之后弹出一个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;

}

@Override

public 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) {

}

}

}

@Override

public 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

@Override

public 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

@Override

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup

container, @Nullable Bundle savedInstanceState) {

return inflater.inflate(R.layout.activity_xia, container, false);

}

@Override

public 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() {

@Override

public void onClick(View view) {

dismiss();

}

});

tv_click.setOnClickListener(new View.OnClickListener() {

@Override

public 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);

}

}

@Override

public 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的接口

@Override

public void inputComplete() {

if (!editText.getEditContent().equals("1234")) {

text.setText("验证码输入错误");

text.setTextColor(Color.RED);

}

}

@Override

public void deleteContent(boolean isDelete) {

if (isDelete) {

text.setText("输入验证码表示同意《用户协议》");

text.setTextColor(Color.BLACK);

}

}

}

至于那个自定义的CountDownTimer在这里有介绍

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

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

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

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

  2. android 好用的自定义倒计时工具(验证码发送倒计时等等)

    可用于短信发送倒计时,请求倒计时等各个地方,使用方便,与组件解耦. import android.os.CountDownTimer; import android.view.View; /*** 倒 ...

  3. android 自定义edittext方框样式,Android之EditText自定义边框和边框颜色(转载)

    介绍一种比较常见的用法 第一步:准备两张图片大小一样,颜色不同的图片.图片名称分为:editbox_focus.png和editbox_normal.png 放入工程的drawable文件夹下. 第二 ...

  4. Android View篇之自定义验证码输入框

    首先,我们来看看实现的是怎么样的效果: 如果我们拿到这样的UI,想到的布局应该是用4个EditText包在横向的LinearLayout里面,但今天要讲的View,所以我们决定用一个自定义的EditT ...

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

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

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

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

  7. android自定义横线,Android实现自带横线的EditText

    (一)问题 怎样实现带有横栏的EditText(像记事本的编辑界面那样)? (二)初步思路 1.通过修改EditText背景来实现(系统背景是一个框形图片,内部透明,替换为一个带有横栏的图片即可) 2 ...

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

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

  9. 【Android游戏开发十七】让玩家自定义手势玩转Android游戏!—Android Gesture之【输入法手势技术】...

    为什么80%的码农都做不了架构师?>>>     李华明Himi 原创,转载务必在明显处注明: 转载自 [黑米GameDev街区] 原文链接:  http://www.himigam ...

最新文章

  1. linux环境变量设置注意事项
  2. glide缩略图存储 android,Glide 显示视频缩略图及遇到的坑
  3. sony电视播放服务器文件,sony电视怎么样 sony电视支持视频格式【图文详解】
  4. loaded the ViewController nib but the view outlet was not set. 处理方式
  5. CentOS安装Samba服务
  6. 分布式数据库进入实时时代,TiDB 5.0 带来了什么?
  7. apache+php+mysq环境详细l配置
  8. java 函数委托_Java反射实现.NET委托
  9. 关于删库 恢复 (慎重使用,未亲测)
  10. 简单的form表单文件上传
  11. Java并发包提供了哪些并发工具类?
  12. cfar(Constant False-Alarm Rate)
  13. 微信小程序之点点考勤经验总结
  14. 台式计算机能装蓝牙吗,台式机如何安装蓝牙
  15. windows server 2016 活动目录部署系列(十一)AD域控上安装证书服务器
  16. 响应国家十四五规划,ABeam(德硕)科技赋能可靠股份数智化转型
  17. 有利于排名的网页标题和描述创作
  18. canvas画一个渐变色的环形进度环
  19. oracle数据库rdo,10_Oracle_Admin_手动创建一个比较实用的数据库
  20. 【Python】利用Python实现精准三点定位(经纬度坐标与平面坐标转换法求解)

热门文章

  1. 基于Matlab虹膜图像的外边界定位
  2. Qt 解决png图片转jpg图片透明背景变成黑色的问题
  3. Echarts模拟迁徙之飞机变小车
  4. Python神经网络1之TensorFlow
  5. 数学小课堂:虚数的媒介工具作用(虚构一个现实中不存在的概念,来解决现实问题)
  6. EI收录的外文期刊(计算机类)
  7. java vue 服务端渲染_vue服务端渲染缓存应用详解
  8. rm 输入/输出错误
  9. 通达信l2接口到底是什么原理?
  10. 秦始皇留下的9个谜团