实现一个类似iphone锁屏时候的密码解锁界面

在工作中,要实现一个类似iphone锁屏时候的密码解锁界面,要求每一个编辑框里输入只能输入一个字符,最后一个输入完成以后,自动执行下一步动作。整体界面如下图:

界面很简单,没有做美化,要控制EditText在每一次输入以后焦点移动到下一个控件上,并且按下删除按钮以后将数据全部删除,需要用到EditText控件中addTextChangedListener方法和setOnKeyListener方法。

当我们给一个editText添加一个addTextChangedListener方法后,需要实现以下几个方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
editText.addTextChangedListener( new  TextWatcher() { 
            
        @Override
        public  void  onTextChanged(CharSequence text,  int  start,  int before,  int  count) { 
        //text  输入框中改变后的字符串信息 
        //start 输入框中改变后的字符串的起始位置 
        //before 输入框中改变前的字符串的位置 默认为0 
        //count 输入框中改变后的一共输入字符串的数量 
            
       
            
        @Override
        public  void  beforeTextChanged(CharSequence text,  int  start, int  count, int  after) { 
        //text  输入框中改变前的字符串信息 
        //start 输入框中改变前的字符串的起始位置 
        //count 输入框中改变前后的字符串改变数量一般为0 
        //after 输入框中改变后的字符串与起始位置的偏移量 
          
       
            
        @Override
        public  void  afterTextChanged(Editable edit) { 
        //edit  输入结束呈现在输入框中的信息 
         
       
    });

具体参数说明已经写清楚了,这里大家可以写一些调试信息,看一下这个接口中方法的调用过程。

在TextWatcher这个接口中,我们要实现onTextChanged、beforeTextChanged、afterTextChanged这三个方法,每当一个EditText的内容发生变化的时候(注意:不管你在什么位置,只要发生变化,这个接口就会监听到),系统会执行这3个方法,执行的步骤依次是:beforeTextChanged→onTextChanged→ afterTextChanged,所以我要实现的功能放到此处执行即可。

其次改界面还要求实现用户按下删除按钮以后,清空所有的数据,这里需要用到的就是EditText的setOnKeyListener 方法了。这里抱怨一下,都是按键,竟然监听的接口不一样,也就是说你按键盘中的各种数字、字母不会进入onkey的监听,只会进入textChange的监听,而按下删除,回车等这些键以后,进入的是onkey的方法~~这样就会导致一些混乱,比如我在onkey的监听中更改了EditText的值,那么系统会立刻执行textChange监听接口的实现,执行过后,再次跳回onkey的监听。如果程序设计不好的话,这里就会出现很多奇怪的现象。

最后该界面要求进入的时候就要显示软键盘,这个在网上查找了一下,实现起来比较简单,在程序清单AndroidManifest.xml中,将这个activity设置软键盘的显示模式,并在初始化时保持一个EditText获取焦点,就会弹出键盘。

android:windowSoftInputMode = "adjustResize"<

!--stateVisible 一直显示键盘 adjustResize 显示键盘时调整布局-->

OK,最后贴出代码,方便以后查阅

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/**
  * 验证码的发送界面
  * @author sC
  *
  */
public  class  VerifyInterface  extends  Activity {
   
  private  View titleView; //标题栏布局
  private  LinearLayout titleLayout; //标题栏布局的容器
  private  Button rightButton; // 退出按钮
  private  ProgressBar waite; // 圆形进度条
  private  TextView txtAlert; //提醒文字
  private  EditText txt1, txt2, txt3, txt4, txt5, txt6; //接收验证码的6个EditText
  private  String code =  "" ; //最后要发送的验证码
  private  EditText[] txts;
  private  static  int  count =  0 ;
   
  protected  void  onCreate(Bundle savedInstanceState) {
   
   super .onCreate(savedInstanceState);
   //设定界面不显示标题栏
   requestWindowFeature(Window.FEATURE_NO_TITLE);
   
   setContentView(R.layout.verifycode);
   initTitle();
   setListener();
   
  }
  /**
   * 发送验证码
   */
  private  void  sendCode() {
   txtAlert.setText( "发送验证码,请稍候...." );
   waite.setVisibility(ProgressBar.VISIBLE);
   for  ( int  i =  0 ; i < txts.length; i++) {
    Log.e( "sc" , String.valueOf(i));
    code += txts[i].getText().toString();
   
   }
   Toast.makeText(VerifyInterface. this , code, Toast.LENGTH_LONG).show();
   
  }
  /**
   * 循环给每个EditText添加监听
   */
  private  void  addTextListener() {
   if  (txts !=  null ) {
    for  ( int  i =  0 ; i < txts.length; i++) {
     txts[i].setOnKeyListener(key);
     txts[i].addTextChangedListener(watcher);
    }
   }
  }
   
  OnKeyListener key =  new  View.OnKeyListener() {
   
   public  boolean  onKey(View view,  int  i, KeyEvent keyevent) {
   
    if  (i == KeyEvent.KEYCODE_DEL) {
     reset();
    }
    return  false ;
   }
  };
  /**
   * 内容改变的监听接口
   */
  TextWatcher watcher =  new  TextWatcher() {
   
   public  void  onTextChanged(CharSequence charsequence,  int  i,  int j,  int  k) {
    /**
     * 如果当前的EditText中没有值,则执行
     */
    if  (j ==  0 ) {
     if  (count < txts.length -  1 ) {
   
      txts[++count].requestFocus();
     else  {
      sendCode();
     }
       
    }
   }
   public  void  beforeTextChanged(CharSequence charsequence,  int  i, int  j,
     int  k) {
   }
   public  void  afterTextChanged(Editable editable) {
   
   }
  };
  /**
   * 清空数据
   */
  public  void  reset() {
   txtAlert.setText( "请输入验证码" );
   waite.setVisibility(ProgressBar.INVISIBLE);
   code =  "" ;
   count =  0 ;
   for  ( int  i =  0 ; i < txts.length; i++) {
    // 清空改变监听
    txts[i].removeTextChangedListener(watcher);
   }
   for  ( int  j =  0 ; j < txts.length; j++) {
    txts[j].setText( "" );
    txts[j].clearFocus();
   }
   txt1.requestFocus();
   addTextListener();
  }
   
  /**
   * 设置监听动作
   */
  private  void  setListener() {
   findView();
   addTextListener();
   buttonListener();
  }
  /**
   * 标题栏右上按钮的监听
   */
  private  void  buttonListener() {
   rightButton.setOnClickListener( new  View.OnClickListener() {
   
    public  void  onClick(View view) {
     reset();
    }
   });
  }
  /**
   * 加载控件
   */
  private  void  findView() {
   txt1 = (EditText) findViewById(R.id.txtCode1);
   txt1.setFocusable( true );
   txt2 = (EditText) findViewById(R.id.txtCode2);
   txt3 = (EditText) findViewById(R.id.txtCode3);
   txt4 = (EditText) findViewById(R.id.txtCode4);
   txt5 = (EditText) findViewById(R.id.txtCode5);
   txt6 = (EditText) findViewById(R.id.txtCode6);
   txts =  new  EditText[] { txt1, txt2, txt3, txt4, txt5, txt6 };
   waite = (ProgressBar) findViewById(R.id.waite);
   rightButton = (Button) titleLayout.findViewById(R.id.nav_rightButton);
   txtAlert = (TextView) findViewById(R.id.txtAlert);
  }
   
  /**
   * 初始化自定义标题栏
   */
  private  void  initTitle() {
   LayoutInflater inflater = (LayoutInflater)  this
     .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   titleView = inflater.inflate(R.layout.title,  null );
   titleLayout = (LinearLayout) findViewById(R.id.topLinearLayout);
   titleLayout.addView(titleView);
   
  }
  /**
   * 当程序因其他原因暂停返回以后,同样清空数据
   */
  protected  void  onResume() {
   reset();
   super .onResume();
  }
    
}

主要布局文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
<?xml version= "1.0"  encoding= "utf-8" ?>
<LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"
     android:layout_width= "fill_parent"
     android:layout_height= "fill_parent"
     android:orientation= "vertical"  >
   
     <LinearLayout
         android:id= "@+id/topLinearLayout"
         android:layout_width= "fill_parent"
         android:layout_height= "wrap_content"
         android:layout_gravity= "top"  >
     </LinearLayout>
    
     <LinearLayout
         android:layout_width= "fill_parent"
         android:layout_height= "fill_parent"
         android:orientation= "vertical"
         android:gravity= "bottom"
         android:layout_gravity= "bottom" >
   
         <TextView
             android:id= "@+id/txtAlert"
             android:layout_width= "wrap_content"
             android:layout_height= "wrap_content"
             android:layout_gravity= "center"
             android:text= "请输入验证码"
             android:textSize= "30sp"  />
   
         <ProgressBar
             android:id= "@+id/waite"
             android:layout_width= "wrap_content"
             android:layout_height= "wrap_content"
             android:layout_gravity= "center"
             android:visibility= "invisible"  />
   
         <LinearLayout
             android:layout_width= "fill_parent"
             android:layout_height= "fill_parent"
             android:orientation= "horizontal"  android:gravity= "bottom"
              >
   
             <EditText
                 android:id= "@+id/txtCode1"
                 android:layout_width= "wrap_content"
                 android:layout_height= "wrap_content"
                 android:layout_weight= "1"
                 android:inputType= "numberSigned"
                 android:maxLength= "1"
                 android:gravity= "center" />
   
             <EditText
                 android:id= "@+id/txtCode2"
                 android:layout_width= "wrap_content"
                 android:layout_height= "wrap_content"
                 android:layout_weight= "1"
                 android:inputType= "numberSigned"
                 android:maxLength= "1"
                 android:gravity= "center" />
   
             <EditText
                 android:id= "@+id/txtCode3"
                 android:layout_width= "wrap_content"
                 android:layout_height= "wrap_content"
                 android:layout_weight= "1"
                 android:inputType= "numberSigned"
                 android:maxLength= "1"
                 android:gravity= "center" />
   
             <EditText
                 android:id= "@+id/txtCode4"
                 android:layout_width= "wrap_content"
                 android:layout_height= "wrap_content"
                 android:layout_weight= "1"
                 android:inputType= "numberSigned"
                 android:maxLength= "1"
                 android:gravity= "center" />
   
             <EditText
                 android:id= "@+id/txtCode5"
                 android:layout_width= "wrap_content"
                 android:layout_height= "wrap_content"
                 android:layout_weight= "1"
                 android:inputType= "numberSigned"
                 android:maxLength= "1"
                 android:gravity= "center" />
   
             <EditText
                 android:id= "@+id/txtCode6"
                 android:layout_width= "wrap_content"
                 android:layout_height= "wrap_content"
                 android:layout_weight= "1"
                 android:inputType= "numberSigned"
                 android:maxLength= "1"
                 android:gravity= "center" />
         </LinearLayout>
     </LinearLayout>
   
</LinearLayout>

标题栏布局文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="55dip"
    android:background="@drawable/title_blue" >
   
    <Button
        android:id="@+id/nav_leftButton"
        android:layout_width="60dip"
        android:layout_height="45dip"
        android:layout_alignParentLeft="true"
            
        android:layout_centerVertical="true"
          
        android:text="返回"
        android:textSize="16sp" />
   
    <TextView
        android:id="@+id/nav_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_toRightOf="@id/nav_leftButton"
         
        android:text="验证"
        android:textSize="20sp" />
   
   
    <Button
        android:id="@+id/nav_rightButton"
        android:layout_width="60dip"
        android:layout_height="45dip"
        android:layout_centerVertical="true"
        android:layout_marginRight="12dip"
           
        android:layout_alignParentRight="true"
        android:text="退出"
        android:textSize="16sp" />
   
</RelativeLayout>


良心的公众号,更多精品文章,不要忘记关注哈

《Android和Java技术栈》



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值