用EditText实现的 连续输入的密码框

来源:互联网 发布:财务会计软件 编辑:程序博客网 时间:2024/04/29 22:41

最近项目要实现如下的密码框样式(实现效果图如下)



先看单个EditText xml配置的属性:

只允许最多输入一个字符

<EditText            android:id="@+id/EditText01"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:gravity="center_horizontal"            android:layout_weight="1"            android:maxLength="1"            android:inputType="numberPassword" />


控件初始化:

private void initView() {editText1 = (EditText) findViewById(R.id.EditText01);editText2 = (EditText) findViewById(R.id.EditText02);editText3 = (EditText) findViewById(R.id.EditText03);editText4 = (EditText) findViewById(R.id.EditText04);editText5 = (EditText) findViewById(R.id.EditText05);editText6 = (EditText) findViewById(R.id.EditText06);//添加TAG 用于textChangeListener的标示editText1.setTag(1);editText2.setTag(2);editText3.setTag(3);editText4.setTag(4);editText5.setTag(5);editText6.setTag(6);//添加 内容change listener :输入焦点后移 + 密码验证editText1.addTextChangedListener(new MyTextChangeWatcher(1));editText2.addTextChangedListener(new MyTextChangeWatcher(2));editText3.addTextChangedListener(new MyTextChangeWatcher(3));editText4.addTextChangedListener(new MyTextChangeWatcher(4));editText5.addTextChangedListener(new MyTextChangeWatcher(5));//editText6.addTextChangedListener(new MyTextChangeWatcher(6));//del 监听,输入焦点前移editText2.setOnKeyListener(keyListener);editText3.setOnKeyListener(keyListener);editText4.setOnKeyListener(keyListener);editText5.setOnKeyListener(keyListener);editText6.setOnKeyListener(keyListener);// test();// testClear();}

用TextWatcher 进行 焦点后移处理:

每个EditText 有内容输入后,通过index把焦点后移一位,然后发送命令,扫描输入框是否都有输入,若都有,则判断密码的有效性。


class MyTextChangeWatcher implements TextWatcher {//标示 绑定的EditTextprivate int index;public MyTextChangeWatcher(int index) {super();this.index = index;}@Overridepublic void afterTextChanged(Editable s) {DEBUG("afterTextChanged --s=" + s.toString());if (s != null && s.length() == 1) {if (index < 6) {// 焦点后移getEditTextFromIndex(index).clearFocus();getEditTextFromIndex(index + 1).requestFocusFromTouch();} else {// TODO 判断// handler.sendEmptyMessage(1);}setFlag(false, index);// 对应标志位 置 1//有内容输入,判断密码是否输入OKhandler.sendEmptyMessage(1);} else {//清除 对应 标识位setFlag(true, index);}}@Overridepublic void beforeTextChanged(CharSequence s, int start, int count,int after) {DEBUG("beforeTextChanged --s=" + s.toString());}@Overridepublic void onTextChanged(CharSequence s, int start, int before,int count) {DEBUG("onTextChanged --s=" + s.toString());}}

扫描  输入框与密码判断:


private Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {//标志位 方法判断if (!checkHasNull()) {// 都 已输入if (judgePassWord()) {DEBUG("密码正确");} else {DEBUG("密码错误");}} else {DEBUG("有输入框未输入值");}//扫描输入框,是否全都已输入if (scanEditTextHasNull()) {return;}//判断 密码有效性if (judgePassWord()) {startActivity(new Intent(MainActivity.this, TMainActivity.class));} else {Toast.makeText(MainActivity.this, "密码输入错误", Toast.LENGTH_SHORT).show();}};};


循环扫描,有空,立即跳出
/** * 扫描EditText 是否存在没有输入的 * @return true 有空, false 都填写值了 */private boolean scanEditTextHasNull() {for (int i = 0; i < 6; i++) {if (getEditTextFromIndex(i + 1).getText() == null|| getEditTextFromIndex(i + 1).getText().length() != 1) {//有一个为空,立即返回return true;}}return false;}


单个字符,循环对比。


/** * 判断密码是否正确 */private boolean judgePassWord() {for (int i = 0; i < 6; i++) {DEBUG("String.valueOf(pw.charAt(0)=" + String.valueOf(pw.charAt(0)));DEBUG("getEditTextFromIndex(i+1).getText()="+ getEditTextFromIndex(i + 1).getText());if (!String.valueOf(pw.charAt(0)).equals(getEditTextFromIndex(i + 1).getText().toString())) {return false;// 有一个密码不符合,就立即跳出}}return true;}



用OnKeyListener 焦点前移:

当前EditText 内容为空,并且del键 按下,焦点前移

/** * 监听删除键 前移焦点 */private OnKeyListener keyListener = new OnKeyListener() {@Overridepublic boolean onKey(View v, int keyCode, KeyEvent event) {DEBUG(" keyCode=" + keyCode + " event=" + event);DEBUG(((EditText) v).getText().toString());if ((((EditText) v).getText().toString() == null || ((EditText) v).getText().toString().isEmpty())&& keyCode == KeyEvent.KEYCODE_DEL&& event.getAction() == KeyEvent.ACTION_DOWN) {// 该EditText的 内容已为空,并且 del 键按下v.clearFocus();// 清除该控件焦点// 将焦点给到前面一个EditTextEditText editText = getEditTextFromIndex(Integer.parseInt(String.valueOf(v.getTag())) - 1);// editText.requestFocus(); //也可以editText.requestFocusFromTouch();}return false;}};


TAG 与EditText 映射

private EditText getEditTextFromIndex(int index) {switch (index) {case 1 :return editText1;case 2 :return editText2;case 3 :return editText3;case 4 :return editText4;case 5 :return editText5;case 6 :return editText6;default :break;}return null;}


关于密码框是否有输入值,除了循环扫描外,还用个人觉得更轻量级一些的方法做了另外一种实现:通过标识位0 和1 来判断,指定位置对应的EditText是否有输入值 :1,有。


设置 指定标志位

/** * 对指定位 进行位操作 *  * @param isNull *            true:当前值为null ,清零。false:有值,该标志位 给1. * @param index *            标志位index */private void setFlag(boolean isNull, int index) {// 得到 唯一一个 1的二进制数 00001000byte b = (byte) (1 << (index - 1));if (isNull) {// 指定 位 清零b = (byte) ~b; // 11110111flag = (byte) (flag & b);} else {// 制定位 赋值 1flag = (byte) (flag | b);}}

判断是否都已输入值

// 判断 是否有未输入的private boolean checkHasNull() {// 00111111if (flag == 0x3f) {return false;}return true;}

标识位 具体变化设置,参见 上面的MyTextChangeWatcher类中的afterTextChanged方法。

代码下载路径:

http://download.csdn.net/detail/luohaowang320/6730955

0 0
原创粉丝点击