EditText 密码框

我自己手头一直用的IOS系统,写这个密码框的时候功能方面也参考了一个下苹果的屏幕解锁。这个密码框也是修修改改两三天才算完善,效果虽然实现了,但很多细节地方还是不太明白,还希望高人指点。


1.功能介绍及效果图

做密码框的时候考虑了两个方案,一个方案是用6个EditText,另一个方案则是在EditText上画5条线。因为我基本没接触过draw部分的代码,对语法都不了解,所以果断选择了第一种。接下来考虑密码框需要实现的功能和用户体验的问题。

iOS 密码显示按钮 苹果按密码出现方块_android

功能1:输入密码删除密码流畅

功能2:用户点击任意密码框焦点在正确的位置

功能3:输入的密码直接显示为圆点

2.源码



[java] 
1. package
2.   
3. import
4. import
5.   
6. import
7. import
8. import
9. import
10. import
11. import
12. import
13. import
14. import
15. import
16. import
17. import
18. import
19. import
20. import
21. import
22. import
23.   
24. public class MainActivity extends Activity implements
25.   
26. private
27. private
28. private
29. private
30. private
31. private
32. private
33. private
34. public int cursorPosition=0;  
35. private
36. public
37. private String[] password=new String[6];  
38. @Override
39. protected void
40. super.onCreate(savedInstanceState);  
41.         setContentView(R.layout.httfund_enter_password);  
42.         intiView();  
43.         setListener();  
44.         testcursorPosition();  
45.     }  
46.       
47. public void
48.         et_pwd1=(EditText)findViewById(R.id.et_pwd1);  
49.         et_pwd2=(EditText)findViewById(R.id.et_pwd2);  
50.         et_pwd3=(EditText)findViewById(R.id.et_pwd3);  
51.         et_pwd4=(EditText)findViewById(R.id.et_pwd4);  
52.         et_pwd5=(EditText)findViewById(R.id.et_pwd5);  
53.         et_pwd6=(EditText)findViewById(R.id.et_pwd6);  
54.           
55. new
56.         et_group.add(et_pwd1);  
57.         et_group.add(et_pwd2);  
58.         et_group.add(et_pwd3);  
59.         et_group.add(et_pwd4);  
60.         et_group.add(et_pwd5);  
61.         et_group.add(et_pwd6);  
62.           
63.     }  
64.       
65. /**
66.      * 输入判断,光标永远在第一个空白格
67.      */
68. public void
69. 0;  
70. for(EditText editView : et_group){  
71. true);  
72.         }  
73.           
74. for(EditText et : et_group){  
75. if(!TextUtils.isEmpty(et.getText().toString())){  
76.                 ++cursorPosition;  
77.                   
78. else{  
79. break;  
80.             }  
81.         }  
82.           
83. if(cursorPosition==6){  
84. 5;  
85.             }  
86.             EditText et=et_group.get(cursorPosition);  
87.             et.requestFocus();  
88.             et.setSelection(et.getText().toString().length());  
89.               
90.             imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);  
91. if(imm.isActive()){  
92. 0, InputMethodManager.HIDE_IMPLICIT_ONLY);  
93.               
94.               
95.         }  
96.         setEditViewEnable();  
97.     }  
98. /**
99.      * 设置EditView的Enable属性
100.      * 仅将包含光标的EditView设置为true
101.      */
102. public void
103. int i=0;  
104. for(EditText et : et_group){  
105. if(i++!=cursorPosition){  
106. false);  
107.             }  
108.         }  
109.     }  
110. /**
111.      * 事件监听
112.      */
113. public void
114. /**
115.          * EditView 监听软键盘,监听删除键
116.          */
117. new
118. @Override
119. public boolean onKey(View v, int
120. // TODO Auto-generated method stub
121. if(keyCode==KeyEvent.KEYCODE_DEL&&event.getAction()==KeyEvent.ACTION_DOWN){  
122.                     testcursorPosition();  
123. "pwd", "删除密码"+Integer.toString(cursorPosition));  
124. if(cursorPosition!=6&&cursorPosition!=0){  
125.                         EditText et=et_group.get(cursorPosition);  
126. if(TextUtils.isEmpty(et.getText().toString())){  
127. 1).setText("");  
128.                         }  
129.                     }  
130.                 }  
131. return false;  
132.                   
133.             }  
134.         };  
135. /**
136.          * EditView的点击事件
137.          */
138. new
139.               
140. @Override
141. public void
142. // TODO Auto-generated method stub
143.                 testcursorPosition();  
144.             }  
145.         };  
146.           
147. for(EditText et : et_group){  
148. this);  
149.             et.setOnKeyListener(onKeyListener);  
150.             et.setOnClickListener(clickListener);  
151.         }  
152.     }  
153.       
154. @Override
155. public void beforeTextChanged(CharSequence s, int start, int
156. int
157. // TODO Auto-generated method stub
158.     }  
159.   
160. @Override
161. public void onTextChanged(CharSequence s, int start, int before, int
162. // TODO Auto-generated method stub
163.         EditText et = et_group.get(cursorPosition);  
164. if(s.length()>1){  
165. 0, 1);  
166.             et.setText(s);  
167.             et.setSelection(s.length());  
168.         }  
169.           
170. if(!TextUtils.isEmpty(et.getText().toString())&&  
171. "*")){  
172.             password[cursorPosition]=et.getText().toString();  
173. "*");  
174. else if(!et.getText().toString().equals("*")){  
175.             password[cursorPosition]=et.getText().toString();  
176.         }  
177.           
178.         testcursorPosition();  
179.     }  
180.   
181. @Override
182. public void
183. // TODO Auto-generated method stub
184.     }  
185. }



package com.example.passwordview;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;

public class MainActivity extends Activity implements TextWatcher{

	private EditText et_pwd1;
	private EditText et_pwd2;
	private EditText et_pwd3;
	private EditText et_pwd4;
	private EditText et_pwd5;
	private EditText et_pwd6;
	private List<EditText> et_group;
	private OnKeyListener onKeyListener;
	public int cursorPosition=0;
	private InputMethodManager imm;
	public Context context;
	private String[] password=new String[6];
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.httfund_enter_password);
		intiView();
		setListener();
		testcursorPosition();
	}
	
	public void intiView(){
		et_pwd1=(EditText)findViewById(R.id.et_pwd1);
		et_pwd2=(EditText)findViewById(R.id.et_pwd2);
		et_pwd3=(EditText)findViewById(R.id.et_pwd3);
		et_pwd4=(EditText)findViewById(R.id.et_pwd4);
		et_pwd5=(EditText)findViewById(R.id.et_pwd5);
		et_pwd6=(EditText)findViewById(R.id.et_pwd6);
		
		et_group=new ArrayList<EditText>();
		et_group.add(et_pwd1);
		et_group.add(et_pwd2);
		et_group.add(et_pwd3);
		et_group.add(et_pwd4);
		et_group.add(et_pwd5);
		et_group.add(et_pwd6);
		
	}
	
	/**
	 * 输入判断,光标永远在第一个空白格
	 */
	public void testcursorPosition(){
		cursorPosition=0;
		for(EditText editView : et_group){
			editView.setFocusableInTouchMode(true);
		}
		
		for(EditText et : et_group){
			if(!TextUtils.isEmpty(et.getText().toString())){
				++cursorPosition;
				
			}else{
				break;
			}
		}
		
			if(cursorPosition==6){
				cursorPosition=5;
			}
			EditText et=et_group.get(cursorPosition);
			et.requestFocus();
			et.setSelection(et.getText().toString().length());
			
			imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
			if(imm.isActive()){
				imm.toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);
			
			
		}
		setEditViewEnable();
	}
	/**
	 * 设置EditView的Enable属性
	 * 仅将包含光标的EditView设置为true
	 */
	public void setEditViewEnable(){
		int i=0;
		for(EditText et : et_group){
			if(i++!=cursorPosition){
				et.setFocusableInTouchMode(false);
			}
		}
	}
	/**
	 * 事件监听
	 */
	public void setListener(){
		/**
		 * EditView 监听软键盘,监听删除键
		 */
		onKeyListener=new OnKeyListener() {
			@Override
			public boolean onKey(View v, int keyCode, KeyEvent event) {
				// TODO Auto-generated method stub
				if(keyCode==KeyEvent.KEYCODE_DEL&&event.getAction()==KeyEvent.ACTION_DOWN){
					testcursorPosition();
					Log.d("pwd", "删除密码"+Integer.toString(cursorPosition));
					if(cursorPosition!=6&&cursorPosition!=0){
						EditText et=et_group.get(cursorPosition);
						if(TextUtils.isEmpty(et.getText().toString())){
							et_group.get(cursorPosition-1).setText("");
						}
					}
				}
					return false;
				
			}
		};
		/**
		 * EditView的点击事件
		 */
		OnClickListener clickListener=new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				testcursorPosition();
			}
		};
		
		for(EditText et : et_group){
			et.addTextChangedListener(this);
			et.setOnKeyListener(onKeyListener);
			et.setOnClickListener(clickListener);
		}
	}
	
	@Override
	public void beforeTextChanged(CharSequence s, int start, int count,
			int after) {
		// TODO Auto-generated method stub
	}

	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {
		// TODO Auto-generated method stub
		EditText et = et_group.get(cursorPosition);
		if(s.length()>1){
			s=s.toString().subSequence(0, 1);
			et.setText(s);
			et.setSelection(s.length());
		}
		
		if(!TextUtils.isEmpty(et.getText().toString())&&
				!et.getText().toString().equals("*")){
			password[cursorPosition]=et.getText().toString();
			et.setText("*");
		}else if(!et.getText().toString().equals("*")){
			password[cursorPosition]=et.getText().toString();
		}
		
		testcursorPosition();
	}

	@Override
	public void afterTextChanged(Editable s) {
		// TODO Auto-generated method stub
	}
}

代码并不难,testcursorPosition用来检测光标应该在的正确位置。InputMethodManager用于显示软键盘,设置成HIDE_IMPLICIT_ONLY唯一的一个问题就是可能弹出密码框的时候会自动弹出软键盘,这个软键盘在弹出后会弹回,但是解决了在输入密码的时候软键盘弹出弹回影响用户体验的问题。在onTextChanged对EditText的长度进行了限制。把数字显示成“*”

整个逻辑跑通之后最大的问题就是输入密码变圆点,如果不直接设置成*号,密码框变成圆点的过程会很长,而且时间不定,体验非常差。


下载地址 :


我自己手头一直用的IOS系统,写这个密码框的时候功能方面也参考了一个下苹果的屏幕解锁。这个密码框也是修修改改两三天才算完善,效果虽然实现了,但很多细节地方还是不太明白,还希望高人指点。


1.功能介绍及效果图

做密码框的时候考虑了两个方案,一个方案是用6个EditText,另一个方案则是在EditText上画5条线。因为我基本没接触过draw部分的代码,对语法都不了解,所以果断选择了第一种。接下来考虑密码框需要实现的功能和用户体验的问题。

iOS 密码显示按钮 苹果按密码出现方块_android

功能1:输入密码删除密码流畅

功能2:用户点击任意密码框焦点在正确的位置

功能3:输入的密码直接显示为圆点

2.源码


[java]   
1. package
2.   
3. import
4. import
5.   
6. import
7. import
8. import
9. import
10. import
11. import
12. import
13. import
14. import
15. import
16. import
17. import
18. import
19. import
20. import
21. import
22. import
23.   
24. public class MainActivity extends Activity implements
25.   
26. private
27. private
28. private
29. private
30. private
31. private
32. private
33. private
34. public int cursorPosition=0;  
35. private
36. public
37. private String[] password=new String[6];  
38. @Override
39. protected void
40. super.onCreate(savedInstanceState);  
41.         setContentView(R.layout.httfund_enter_password);  
42.         intiView();  
43.         setListener();  
44.         testcursorPosition();  
45.     }  
46.       
47. public void
48.         et_pwd1=(EditText)findViewById(R.id.et_pwd1);  
49.         et_pwd2=(EditText)findViewById(R.id.et_pwd2);  
50.         et_pwd3=(EditText)findViewById(R.id.et_pwd3);  
51.         et_pwd4=(EditText)findViewById(R.id.et_pwd4);  
52.         et_pwd5=(EditText)findViewById(R.id.et_pwd5);  
53.         et_pwd6=(EditText)findViewById(R.id.et_pwd6);  
54.           
55. new
56.         et_group.add(et_pwd1);  
57.         et_group.add(et_pwd2);  
58.         et_group.add(et_pwd3);  
59.         et_group.add(et_pwd4);  
60.         et_group.add(et_pwd5);  
61.         et_group.add(et_pwd6);  
62.           
63.     }  
64.       
65. /**
66.      * 输入判断,光标永远在第一个空白格
67.      */
68. public void
69. 0;  
70. for(EditText editView : et_group){  
71. true);  
72.         }  
73.           
74. for(EditText et : et_group){  
75. if(!TextUtils.isEmpty(et.getText().toString())){  
76.                 ++cursorPosition;  
77.                   
78. else{  
79. break;  
80.             }  
81.         }  
82.           
83. if(cursorPosition==6){  
84. 5;  
85.             }  
86.             EditText et=et_group.get(cursorPosition);  
87.             et.requestFocus();  
88.             et.setSelection(et.getText().toString().length());  
89.               
90.             imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);  
91. if(imm.isActive()){  
92. 0, InputMethodManager.HIDE_IMPLICIT_ONLY);  
93.               
94.               
95.         }  
96.         setEditViewEnable();  
97.     }  
98. /**
99.      * 设置EditView的Enable属性
100.      * 仅将包含光标的EditView设置为true
101.      */
102. public void
103. int i=0;  
104. for(EditText et : et_group){  
105. if(i++!=cursorPosition){  
106. false);  
107.             }  
108.         }  
109.     }  
110. /**
111.      * 事件监听
112.      */
113. public void
114. /**
115.          * EditView 监听软键盘,监听删除键
116.          */
117. new
118. @Override
119. public boolean onKey(View v, int
120. // TODO Auto-generated method stub
121. if(keyCode==KeyEvent.KEYCODE_DEL&&event.getAction()==KeyEvent.ACTION_DOWN){  
122.                     testcursorPosition();  
123. "pwd", "删除密码"+Integer.toString(cursorPosition));  
124. if(cursorPosition!=6&&cursorPosition!=0){  
125.                         EditText et=et_group.get(cursorPosition);  
126. if(TextUtils.isEmpty(et.getText().toString())){  
127. 1).setText("");  
128.                         }  
129.                     }  
130.                 }  
131. return false;  
132.                   
133.             }  
134.         };  
135. /**
136.          * EditView的点击事件
137.          */
138. new
139.               
140. @Override
141. public void
142. // TODO Auto-generated method stub
143.                 testcursorPosition();  
144.             }  
145.         };  
146.           
147. for(EditText et : et_group){  
148. this);  
149.             et.setOnKeyListener(onKeyListener);  
150.             et.setOnClickListener(clickListener);  
151.         }  
152.     }  
153.       
154. @Override
155. public void beforeTextChanged(CharSequence s, int start, int
156. int
157. // TODO Auto-generated method stub
158.     }  
159.   
160. @Override
161. public void onTextChanged(CharSequence s, int start, int before, int
162. // TODO Auto-generated method stub
163.         EditText et = et_group.get(cursorPosition);  
164. if(s.length()>1){  
165. 0, 1);  
166.             et.setText(s);  
167.             et.setSelection(s.length());  
168.         }  
169.           
170. if(!TextUtils.isEmpty(et.getText().toString())&&  
171. "*")){  
172.             password[cursorPosition]=et.getText().toString();  
173. "*");  
174. else if(!et.getText().toString().equals("*")){  
175.             password[cursorPosition]=et.getText().toString();  
176.         }  
177.           
178.         testcursorPosition();  
179.     }  
180.   
181. @Override
182. public void
183. // TODO Auto-generated method stub
184.     }  
185. }

  



package com.example.passwordview;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;

public class MainActivity extends Activity implements TextWatcher{

	private EditText et_pwd1;
	private EditText et_pwd2;
	private EditText et_pwd3;
	private EditText et_pwd4;
	private EditText et_pwd5;
	private EditText et_pwd6;
	private List<EditText> et_group;
	private OnKeyListener onKeyListener;
	public int cursorPosition=0;
	private InputMethodManager imm;
	public Context context;
	private String[] password=new String[6];
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.httfund_enter_password);
		intiView();
		setListener();
		testcursorPosition();
	}
	
	public void intiView(){
		et_pwd1=(EditText)findViewById(R.id.et_pwd1);
		et_pwd2=(EditText)findViewById(R.id.et_pwd2);
		et_pwd3=(EditText)findViewById(R.id.et_pwd3);
		et_pwd4=(EditText)findViewById(R.id.et_pwd4);
		et_pwd5=(EditText)findViewById(R.id.et_pwd5);
		et_pwd6=(EditText)findViewById(R.id.et_pwd6);
		
		et_group=new ArrayList<EditText>();
		et_group.add(et_pwd1);
		et_group.add(et_pwd2);
		et_group.add(et_pwd3);
		et_group.add(et_pwd4);
		et_group.add(et_pwd5);
		et_group.add(et_pwd6);
		
	}
	
	/**
	 * 输入判断,光标永远在第一个空白格
	 */
	public void testcursorPosition(){
		cursorPosition=0;
		for(EditText editView : et_group){
			editView.setFocusableInTouchMode(true);
		}
		
		for(EditText et : et_group){
			if(!TextUtils.isEmpty(et.getText().toString())){
				++cursorPosition;
				
			}else{
				break;
			}
		}
		
			if(cursorPosition==6){
				cursorPosition=5;
			}
			EditText et=et_group.get(cursorPosition);
			et.requestFocus();
			et.setSelection(et.getText().toString().length());
			
			imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
			if(imm.isActive()){
				imm.toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);
			
			
		}
		setEditViewEnable();
	}
	/**
	 * 设置EditView的Enable属性
	 * 仅将包含光标的EditView设置为true
	 */
	public void setEditViewEnable(){
		int i=0;
		for(EditText et : et_group){
			if(i++!=cursorPosition){
				et.setFocusableInTouchMode(false);
			}
		}
	}
	/**
	 * 事件监听
	 */
	public void setListener(){
		/**
		 * EditView 监听软键盘,监听删除键
		 */
		onKeyListener=new OnKeyListener() {
			@Override
			public boolean onKey(View v, int keyCode, KeyEvent event) {
				// TODO Auto-generated method stub
				if(keyCode==KeyEvent.KEYCODE_DEL&&event.getAction()==KeyEvent.ACTION_DOWN){
					testcursorPosition();
					Log.d("pwd", "删除密码"+Integer.toString(cursorPosition));
					if(cursorPosition!=6&&cursorPosition!=0){
						EditText et=et_group.get(cursorPosition);
						if(TextUtils.isEmpty(et.getText().toString())){
							et_group.get(cursorPosition-1).setText("");
						}
					}
				}
					return false;
				
			}
		};
		/**
		 * EditView的点击事件
		 */
		OnClickListener clickListener=new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				testcursorPosition();
			}
		};
		
		for(EditText et : et_group){
			et.addTextChangedListener(this);
			et.setOnKeyListener(onKeyListener);
			et.setOnClickListener(clickListener);
		}
	}
	
	@Override
	public void beforeTextChanged(CharSequence s, int start, int count,
			int after) {
		// TODO Auto-generated method stub
	}

	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {
		// TODO Auto-generated method stub
		EditText et = et_group.get(cursorPosition);
		if(s.length()>1){
			s=s.toString().subSequence(0, 1);
			et.setText(s);
			et.setSelection(s.length());
		}
		
		if(!TextUtils.isEmpty(et.getText().toString())&&
				!et.getText().toString().equals("*")){
			password[cursorPosition]=et.getText().toString();
			et.setText("*");
		}else if(!et.getText().toString().equals("*")){
			password[cursorPosition]=et.getText().toString();
		}
		
		testcursorPosition();
	}

	@Override
	public void afterTextChanged(Editable s) {
		// TODO Auto-generated method stub
	}
}

代码并不难,testcursorPosition用来检测光标应该在的正确位置。InputMethodManager用于显示软键盘,设置成HIDE_IMPLICIT_ONLY唯一的一个问题就是可能弹出密码框的时候会自动弹出软键盘,这个软键盘在弹出后会弹回,但是解决了在输入密码的时候软键盘弹出弹回影响用户体验的问题。在onTextChanged对EditText的长度进行了限制。把数字显示成“*”

整个逻辑跑通之后最大的问题就是输入密码变圆点,如果不直接设置成*号,密码框变成圆点的过程会很长,而且时间不定,体验非常差。