仿微信支付宝支付密码
效果图:
一、主要知识点
- GridLayout的应用
- EditText的textCursorDrawable的应用
- InputMethodManager的应用
- TextWatcher的应用
- OnKeyListener的应用
二、xml布局
colors.xml文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="bg_list">#FFFFFF</color>
<color name="bg_layout">#F0EFF5</color>
</resources>
styles.xml文件
<resources>
<style name="edittext_style">
<item name="android:layout_marginLeft">1dp</item>
<item name="android:layout_marginTop">1dp</item>
<item name="android:layout_marginBottom">1dp</item>
<item name="android:inputType">numberPassword</item>
<item name="android:maxEms">1</item>
</style>
</resources>
在这里,调试的时候发现,设置maxEms没有效果。而且有的手机上调试(比如红米1s,猜测是minAPI的问题),inputType类型为numberPassword并不能输入数字,但在pad和华为等手机上都是有效的。本程序效果图是用华为手机。
layout_password.xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/pwd_ll"
android:orientation="vertical">
<LinearLayout
android:orientation="vertical"
android:background="@drawable/radus_shape"
android:layout_width="match_parent"
android:layout_height="200dp">
<LinearLayout
android:background="@drawable/radus_shape"
android:layout_width="match_parent"
android:layout_height="44dp"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16dp"
android:text="请输入密码,以验证身份"/>
</LinearLayout>
<LinearLayout
android:background="@drawable/radus_shape"
android:layout_width="match_parent"
android:layout_height="80dp"
android:orientation="horizontal"
android:gravity="center">
<GridLayout
android:background="@color/bg_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:columnCount="6"
android:rowCount="1">
<EditText
android:maxEms="1"
android:textCursorDrawable="@color/bg_list"
android:id="@+id/pwd_et1"
style="@style/edittext_style"
android:gravity="center"
android:background="@color/bg_list"
android:layout_width="50dp"
android:layout_height="44dp"
android:layout_row="0"
android:layout_column="0"
android:maxLength="1"
/>
<EditText
android:maxEms="1"
android:textCursorDrawable="@color/bg_list"
android:id="@+id/pwd_et2"
style="@style/edittext_style"
android:gravity="center"
android:background="@color/bg_list"
android:layout_width="50dp"
android:layout_height="44dp"
android:layout_row="0"
android:layout_column="1"
android:maxLength="1"
/>
<EditText
android:maxEms="1"
android:textCursorDrawable="@color/bg_list"
android:id="@+id/pwd_et3"
style="@style/edittext_style"
android:gravity="center"
android:background="@color/bg_list"
android:layout_width="50dp"
android:layout_height="44dp"
android:layout_row="0"
android:layout_column="2"
android:maxLength="1"
/>
<EditText
android:maxEms="1"
android:textCursorDrawable="@color/bg_list"
android:id="@+id/pwd_et4"
style="@style/edittext_style"
android:gravity="center"
android:background="@color/bg_list"
android:layout_width="50dp"
android:layout_height="44dp"
android:layout_row="0"
android:layout_column="3"
android:maxLength="1"
/>
<EditText
android:maxEms="1"
android:textCursorDrawable="@color/bg_list"
android:id="@+id/pwd_et5"
style="@style/edittext_style"
android:gravity="center"
android:background="@color/bg_list"
android:layout_width="50dp"
android:layout_height="44dp"
android:layout_row="0"
android:layout_column="4"
android:maxLength="1"
/>
<EditText
android:maxEms="1"
android:textCursorDrawable="@color/bg_list"
android:id="@+id/pwd_et6"
style="@style/edittext_style"
android:gravity="center"
android:background="@color/bg_list"
android:layout_width="50dp"
android:layout_height="44dp"
android:layout_row="0"
android:layout_column="5"
android:layout_marginRight="1dp"
android:maxLength="1"
/>
</GridLayout>
</LinearLayout>
<RelativeLayout
android:layout_marginTop="20dp"
android:layout_width="match_parent"
android:layout_height="44dp"
>
<Button
android:layout_marginRight="20dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:id="@+id/pwd_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始"/>
</RelativeLayout>
</LinearLayout>
</LinearLayout>
这里将GridLayout背景色设置为灰色android:background=”@color/bg_layout”,而且设置为一行六列,android:columnCount=”6” android:rowCount=”1”,没一行都用EditText填充,EditText距离父控件为1dp,背景色为白色android:background=”@color/bg_list”,这样格子就形成了。光标颜色设置为与背景色一致,这样就看不到光标闪动了android:textCursorDrawable=”@color/bg_list”
activity.xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:context="com.yds.administrator.myapplication.MainActivity">
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="输入密码" />
</LinearLayout>
这样,布局文件就完成了。下面来介绍一下java代码。
三、Java代码
下面是删除代码:
View.OnKeyListener onKeyListener = new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(et2.getText().toString().length()==0&&et2.isFocusable()){
if (keyCode == KeyEvent.KEYCODE_DEL
&& event.getAction() == KeyEvent.ACTION_DOWN){
et2.clearFocus();
et2.setFocusable(false);
et1.setText("");
et1.setFocusable(true);
et1.setFocusableInTouchMode(true);
et1.requestFocus();
et1.findFocus();
}
}
if(et3.getText().toString().length()==0&&et3.isFocusable()){
if (keyCode == KeyEvent.KEYCODE_DEL
&& event.getAction() == KeyEvent.ACTION_DOWN){
et3.clearFocus();
et3.setFocusable(false);
et2.setText("");
et2.setFocusable(true);
et2.setFocusableInTouchMode(true);
et2.requestFocus();
et2.findFocus();
}
}
if(et4.getText().toString().length()==0&&et4.isFocusable()){
if (keyCode == KeyEvent.KEYCODE_DEL
&& event.getAction() == KeyEvent.ACTION_DOWN){
et4.clearFocus();
et4.setFocusable(false);
et3.setText("");
et3.setFocusable(true);
et3.setFocusableInTouchMode(true);
et3.requestFocus();
et3.findFocus();
}
}
if(et5.getText().toString().length()==0&&et5.isFocusable()){
if (keyCode == KeyEvent.KEYCODE_DEL
&& event.getAction() == KeyEvent.ACTION_DOWN){
et5.clearFocus();
et5.setFocusable(false);
et4.setText("");
et4.setFocusable(true);
et4.setFocusableInTouchMode(true);
et4.requestFocus();
et4.findFocus();
}
}
if(et6.isFocusable()){
if (keyCode == KeyEvent.KEYCODE_DEL
&& event.getAction() == KeyEvent.ACTION_DOWN&&et6.length()==0){
et6.clearFocus();
et6.setFocusable(false);
et5.setText("");
et5.setFocusable(true);
et5.setFocusableInTouchMode(true);
et5.requestFocus();
et5.findFocus();
}
else if(keyCode == KeyEvent.KEYCODE_DEL
&& event.getAction() == KeyEvent.ACTION_DOWN&&et6.length()==1){
et6.setText("");
}
}
return true;
}
};
这里是一个软键盘监听事件,当我们按del(也就是删除键)时,我们将删除内容。因为这里的布局是6个EditText,所以我们要判断EditText是否为空,是否获得焦点。如果为空,且获得焦点,并按了del键,则删除前一个EditText的内容,且前一个EditText获得焦点。
//判断是否按下删除键
if (keyCode == KeyEvent.KEYCODE_DEL
&& event.getAction() == KeyEvent.ACTION_DOWN)
还有一点,当editText被设置et5.setFocusable(false)后,就必须要经过以下3步才能再次获得焦点
et5.setFocusable(true);
et5.setFocusableInTouchMode(true);
et5.requestFocus();
然后我们再看看写入代码:
editTextFocusable(et1,et2,et3,et4,et5,et6);
TextWatcher textWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
//s--未改变之前的内容
//start--内容被改变的开始位置
//count--原始文字被删除的个数
//after--新添加的内容的个数
//---------start和count结合从s中获取被删除的内容-------
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//s--改变之后的新内容
//start--内容被改变的开始位置
//before--原始文字被删除的个数
//count--新添加的内容的个数
//---------start和count结合从s中获取新添加的内容-------
}
@Override
public void afterTextChanged(Editable s) {
//s--最终内容
if(et1.getText().toString().length()==1&&et2.getText().toString().length()==0){
et1.clearFocus();
et1.setFocusable(false);
et2.setFocusable(true);
et2.setFocusableInTouchMode(true);
et2.requestFocus();
et2.findFocus();
}
if (et2.getText().toString().length()==1&&et3.getText().toString().length()==0){
et2.clearFocus();
et2.setFocusable(false);
et3.setFocusable(true);
et3.setFocusableInTouchMode(true);
et3.requestFocus();
et3.findFocus();
}
if (et3.getText().toString().length()==1&&et4.getText().toString().length()==0){
et3.clearFocus();
et3.setFocusable(false);
et4.setFocusable(true);
et4.setFocusableInTouchMode(true);
et4.requestFocus();
et4.findFocus();
}
if (et4.getText().toString().length()==1&&et5.getText().toString().length()==0){
et4.clearFocus();
et4.setFocusable(false);
et5.setFocusable(true);
et5.setFocusableInTouchMode(true);
et5.requestFocus();
et5.findFocus();
}
if (et5.getText().toString().length()==1&&et6.getText().toString().length()==0){
et5.clearFocus();
et5.setFocusable(false);
et6.setFocusable(true);
et6.setFocusableInTouchMode(true);
et6.requestFocus();
et6.findFocus();
}
}
};
这里,我们用TextWatcher来观察输入框中输入的内容。在使用TextWatcher之前先让et2,et3,et4,et5,et6失去焦点,防止用户自己点击其他EditText使其获取焦点。若et1长度为1,且et2长度为0,则et1失去焦点,et2获取焦点.
InputMethodManager应用:
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInputFromInputMethod(et1.getWindowToken(), 0);
}
});
dialog.show();
这里的作用是自动弹出软键盘,但我测试时,是不管用的,在pad上测试还管用。
下面是完整代码:
package com.yds.administrator.myapplication;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
passwordDialog();
}
});
}
private void passwordDialog(){
LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(R.layout.layout_password, null);
final EditText et1 = (EditText) view.findViewById(R.id.pwd_et1);
final EditText et2 = (EditText) view.findViewById(R.id.pwd_et2);
final EditText et3 = (EditText) view.findViewById(R.id.pwd_et3);
final EditText et4 = (EditText) view.findViewById(R.id.pwd_et4);
final EditText et5 = (EditText) view.findViewById(R.id.pwd_et5);
final EditText et6 = (EditText) view.findViewById(R.id.pwd_et6);
Button pwd_btn = (Button) view.findViewById(R.id.pwd_btn);
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setView(view);
final AlertDialog dialog = builder.create();
// Window window=dialog.getWindow();
// window.setGravity(Gravity.CENTER);
// WindowManager.LayoutParams lp=window.getAttributes();
// lp.x=0;
// lp.y=0;
// lp.width = 300;
// window.setAttributes(lp);
pwd_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(et1.length()==1&&et2.length()==1&&et3.length()==1&et4.length()==1&&et5.length()==1&&et6.length()==1){
//可以在这里判断输入的密码是否正确,这里方法有点繁琐,将et1到et6里的内容组成一个字符串,然后再和密码匹配
dialog.dismiss();
Toast.makeText(MainActivity.this, "密码输入正确", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(MainActivity.this,"密码输入错误",Toast.LENGTH_SHORT).show();
}
}
});
View.OnKeyListener onKeyListener = new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(et2.getText().toString().length()==0&&et2.isFocusable()){
if (keyCode == KeyEvent.KEYCODE_DEL
&& event.getAction() == KeyEvent.ACTION_DOWN){
et2.clearFocus();
et2.setFocusable(false);
et1.setText("");
et1.setFocusable(true);
et1.setFocusableInTouchMode(true);
et1.requestFocus();
et1.findFocus();
}
}
if(et3.getText().toString().length()==0&&et3.isFocusable()){
if (keyCode == KeyEvent.KEYCODE_DEL
&& event.getAction() == KeyEvent.ACTION_DOWN){
et3.clearFocus();
et3.setFocusable(false);
et2.setText("");
et2.setFocusable(true);
et2.setFocusableInTouchMode(true);
et2.requestFocus();
et2.findFocus();
}
}
if(et4.getText().toString().length()==0&&et4.isFocusable()){
if (keyCode == KeyEvent.KEYCODE_DEL
&& event.getAction() == KeyEvent.ACTION_DOWN){
et4.clearFocus();
et4.setFocusable(false);
et3.setText("");
et3.setFocusable(true);
et3.setFocusableInTouchMode(true);
et3.requestFocus();
et3.findFocus();
}
}
if(et5.getText().toString().length()==0&&et5.isFocusable()){
if (keyCode == KeyEvent.KEYCODE_DEL
&& event.getAction() == KeyEvent.ACTION_DOWN){
et5.clearFocus();
et5.setFocusable(false);
et4.setText("");
et4.setFocusable(true);
et4.setFocusableInTouchMode(true);
et4.requestFocus();
et4.findFocus();
}
}
if(et6.isFocusable()){
if (keyCode == KeyEvent.KEYCODE_DEL
&& event.getAction() == KeyEvent.ACTION_DOWN&&et6.length()==0){
et6.clearFocus();
et6.setFocusable(false);
et5.setText("");
et5.setFocusable(true);
et5.setFocusableInTouchMode(true);
et5.requestFocus();
et5.findFocus();
}
else if(keyCode == KeyEvent.KEYCODE_DEL
&& event.getAction() == KeyEvent.ACTION_DOWN&&et6.length()==1){
et6.setText("");
}
}
return true;
}
};
editTextFocusable(et1,et2,et3,et4,et5,et6);
TextWatcher textWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if(et1.getText().toString().length()==1&&et2.getText().toString().length()==0){
et1.clearFocus();
et1.setFocusable(false);
et2.setFocusable(true);
et2.setFocusableInTouchMode(true);
et2.requestFocus();
et2.findFocus();
}
if (et2.getText().toString().length()==1&&et3.getText().toString().length()==0){
et2.clearFocus();
et2.setFocusable(false);
et3.setFocusable(true);
et3.setFocusableInTouchMode(true);
et3.requestFocus();
et3.findFocus();
}
if (et3.getText().toString().length()==1&&et4.getText().toString().length()==0){
et3.clearFocus();
et3.setFocusable(false);
et4.setFocusable(true);
et4.setFocusableInTouchMode(true);
et4.requestFocus();
et4.findFocus();
}
if (et4.getText().toString().length()==1&&et5.getText().toString().length()==0){
et4.clearFocus();
et4.setFocusable(false);
et5.setFocusable(true);
et5.setFocusableInTouchMode(true);
et5.requestFocus();
et5.findFocus();
}
if (et5.getText().toString().length()==1&&et6.getText().toString().length()==0){
et5.clearFocus();
et5.setFocusable(false);
et6.setFocusable(true);
et6.setFocusableInTouchMode(true);
et6.requestFocus();
et6.findFocus();
}
}
};
et1.setOnKeyListener(onKeyListener);
et2.setOnKeyListener(onKeyListener);
et3.setOnKeyListener(onKeyListener);
et4.setOnKeyListener(onKeyListener);
et5.setOnKeyListener(onKeyListener);
et6.setOnKeyListener(onKeyListener);
et1.addTextChangedListener(textWatcher);
et2.addTextChangedListener(textWatcher);
et3.addTextChangedListener(textWatcher);
et4.addTextChangedListener(textWatcher);
et5.addTextChangedListener(textWatcher);
et6.addTextChangedListener(textWatcher);
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInputFromInputMethod(et1.getWindowToken(), 0);
}
});
dialog.show();
}
private void editTextFocusable(EditText et1,EditText et2,EditText et3,EditText et4,EditText et5,EditText et6){
et2.setFocusable(false);
et3.setFocusable(false);
et4.setFocusable(false);
et5.setFocusable(false);
et6.setFocusable(false);
}
}