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

本文介绍了如何在Android中使用EditText实现连续输入的密码框效果。通过限制EditText最多输入一个字符并设置焦点转移,实现在每个输入框填满后自动检查密码有效性。此外,还提供了通过标识位来判断输入值的轻量级方法。完整代码可在优快云下载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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



先看单个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 {
		//标示 绑定的EditText
		private int index;

		public MyTextChangeWatcher(int index) {
			super();
			this.index = index;
		}

		@Override
		public 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
				//有内容输入,判断密码是否输入OK
				handler.sendEmptyMessage(1);

			} else {
				//清除 对应 标识位
				setFlag(true, index);
			}
		}

		@Override
		public void beforeTextChanged(CharSequence s, int start, int count,
				int after) {
			DEBUG("beforeTextChanged --s=" + s.toString());

		}

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

		@Override
		public 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();// 清除该控件焦点
				// 将焦点给到前面一个EditText
				EditText 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的二进制数 00001000
		byte b = (byte) (1 << (index - 1));
		if (isNull) {// 指定 位 清零
			b = (byte) ~b; // 11110111
			flag = (byte) (flag & b);
		} else {// 制定位 赋值 1
			flag = (byte) (flag | b);
		}
	}

判断是否都已输入值

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

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

代码下载路径:

http://download.youkuaiyun.com/detail/luohaowang320/6730955

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值