Android高仿微信支付密码输入控件
像微信支付密码控件,在app中是一个多么司空见惯的功能。最近,项目需要这个功能,于是乎就实现这个功能。
老样子,投篮需要找准角度,变成需要理清思路。对于这个"小而美"的控件,我们思路应该这样子。
Ⅰ、将要输入密码数量动态通过代码加载出来。
Ⅱ、利用Gridview模拟产生一个输入数字键盘,并且按照习惯从屏幕底部弹出来。
Ⅲ、对输入数字键盘进行事件监听,将这个输入数字填入到这个密码框中,并且当您输入密码长度一致的时候,进行事件回调。
这个思维导图应该是这样的:
首先,我们要根据需求动态加载密码框,相应的代码如下:
复制代码
for(inti=0;i<6;i++){
TextViewtextView=newTextView(context);
android.widget.LinearLayout.LayoutParamslayoutParams=newandroid.widget.LinearLayout.LayoutParams(
0,android.widget.LinearLayout.LayoutParams.WRAP_CONTENT,1);
textView.setGravity(Gravity.CENTER);
textView.setTransformationMethod(PasswordTransformationMethod.getInstance());
textView.setTextSize(32);
textView.setLayoutParams(layoutParams);
ll_pwd.addView(textView);
if(i!=5){
Viewview2=newView(context);
android.widget.LinearLayout.LayoutParamslayoutParams1=newandroid.widget.LinearLayout.LayoutParams(
1,
android.widget.LinearLayout.LayoutParams.MATCH_PARENT,
0);
view2.setLayoutParams(layoutParams1);
view2.setBackgroundColor(Color.parseColor("#999999"));
ll_pwd.addView(view2);
}
tvList[i]=textView;
}
复制代码
我们这里密码长度设置为6,将这6个密码框控件添加到盛放这些控件的父控件中去,并且每个密码控件中都有一个分隔控件。并且把每个密码输入控件放入控件数组,以便我们进行接下来的操作。
然后了,我们利用Gridview产生一个12宫格的模拟数字键盘,这样模拟键盘样子是这样的:
源代码应该是这样的:
复制代码
/
加载数据的代码
/
privatevoidinitData(){
/初始化按钮上应该显示的数字/
for(inti=1;i<13;i++){
Mapmap=newHashMap();
if(i<10){
map.put("name",String.valueOf(i));
}elseif(i==10){
map.put("name","");
}elseif(i==11){
map.put("name",String.valueOf(0));
}elseif(i==12){
map.put("name","×");
}else{
map.put("name","");
}
valueList.add(map);
}
gridView.setAdapter(adapter);
gridView.setOnItemClickListener(newAdapterView.OnItemClickListener(){
@Override
publicvoidonItemClick(AdapterView>parent,Viewview,
intposition,longid){
if(position<11&&position!=9){//点击0~9按钮
if(currentIndex>=-1&¤tIndex<5){//判断输入位置————要小心数组越界
tvList[++currentIndex].setText(valueList.get(position)
.get("name"));
}
}else{
if(position==11){//点击退格键
if(currentIndex-1>=-1){//判断是否删除完毕————要小心数组越界
tvList[currentIndex--].setText("");
}
}
}
}
});
}
/
GrideView的适配器
/
BaseAdapteradapter=newBaseAdapter(){
@Override
publicintgetCount(){
returnvalueList.size();
}
@Override
publicObjectgetItem(intposition){
returnvalueList.get(position);
}
@Override
publiclonggetItemId(intposition){
returnposition;
}
@SuppressWarnings("deprecation")
@Override
publicViewgetView(intposition,ViewconvertView,ViewGroupparent){
ViewHolderviewHolder;
if(convertView==null){
convertView=View.inflate(context,R.layout.item_gride,null);
viewHolder=newViewHolder();
viewHolder.btnKey=(TextView)convertView
.findViewById(R.id.btn_keys);
convertView.setTag(viewHolder);
}else{
viewHolder=(ViewHolder)convertView.getTag();
}
viewHolder.btnKey.setText(valueList.get(position).get("name"));
if(position==9||position==11){
viewHolder.btnKey.setBackgroundDrawable(Utils.getStateListDrawable(context));
viewHolder.btnKey.setEnabled(false);
}
if(position==11){
viewHolder.btnKey.setBackgroundDrawable(Utils.getStateListDrawable(context));
}
returnconvertView;
}
};
/
存放控件
/
publicfinalclassViewHolder{
publicTextViewbtnKey;
}
复制代码
加载模拟键盘上的数据为0-9与x,然后将这个数据通过一个适配器将这些数据填充到这个Gridview控件。这些都是老司机的老套路。按照惯例,这个模拟键盘应该从屏幕的底部弹出,我这里所做的就是将Gridview依附在popupwindow,然后在从屏幕的底部进行弹出。相应的代码如下:
复制代码
ViewcontentView=LayoutInflater.from(context).inflate(
R.layout.layout_popupdemo,null);//定义后退弹出框
gridView=(GridView)contentView.findViewById(R.id.gv_keybord);//泡泡窗口的布局
popupWindow=newPopupWindow(contentView,
ViewGroup.LayoutParams.MATCH_PARENT,//width
ViewGroup.LayoutParams.WRAP_CONTENT);//higth
popupWindow.setFocuwww.wang027.comsable(false);
popupWindow.setAnimationStyle(R.style.animation);
//从底部弹出
publicvoidshow(){
popupWindow.showAtLocation(rl_bottom,Gravity.BOTTOM,0,0);//确定在界面中出现的位置
}
@Override
publicvoidonWindowFocusChanged(booleanhasWindowFocus){
super.onWindowFocusChanged(hasWindowFocus);
show();
}
复制代码
当这个控件一加载的时候,就弹出。
最后,我们要做的就是监听模拟键盘,将这个模拟键盘的输入填入到密码框,说的貌似很高大上的,其实就是监听Gridview的onitemclick事件,相应代码如下:
复制代码
gridView.setOnItemClickListener(newAdapterView.OnItemClickListener(){
@Override
publicvoidonItemClick(AdapterView>parent,Viewview,
intposition,longid){
if(position<11&&position!=9){//点击0~9按钮
if(currentIndex>=-1&¤tIndex<5){//判断输入位置————要小心数组越界
tvList[++currentIndex].setText(valueList.get(position)
.get("name"));
}
}else{
if(position==11){//点击退格键
if(currentIndex-1>=-1){//判断是否删除完毕————要小心数组越界
tvList[currentIndex--].setText("");
}
}
}
}
});
复制代码
如果用户点击数字0-9,就填入到密码框中,如果是点击退格键的话,就删除所对应密码框的内容。看到没,上文所用文本框数组列表派上了用场。这里值得指出,由于退格键点击效果与众不同,我这里应用代码设置他的样式。
当用户最后一个密码框输入完成之后,就进行输入完成的回调,相应代码为:
复制代码
//设置监听方法,在第6位输入完成后触发
publicvoidsetOnFinishInput(finalOnPasswordInputFinishpass){
tvList[5].addTextChangedListwww.baiyuewang.netener(newTextWatcher(){
@Override
publicvoidbeforeTextChanged(CharSequences,intstart,intcount,
intafter){
}
@Override
publicvoidonTextChanged(CharSequences,intstart,intbefore,
intcount){
}
@Override
publicvoidafterTextChanged(Editables){
if(s.toString().length()==1){
strPassword="";//每次触发都要先将strPassword置空,再重新获取,避免由于输入删除再输入造成混乱
for(inti=0;i<6;i++){
strPassword+=tvList[i].getText().toString().trim();
}
if(pass!=null){
pass.inputFinish();//接口中要实现的方法,完成密码输入完成后的响应逻辑
}
}
}
});
|
|