栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

Android实现支付宝6位密码输入界面

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android实现支付宝6位密码输入界面

 我们先来照图分析一下:
(1)限制输入6位,每一位都有自己的框格,每个格显示一位;
(2)有回退/取消支付按钮;
(3)有忘记密码链接;
(4)自定义的只能输入数字的键盘输入区;
(5)在6位输完后自动进行密码校验和支付交易。如上图左边是iOS支付宝支付密码输入控件,右边是我模仿实现的效果。

首先,我们需要一个页面来完成以上的静态布局,.xml代码如下:

 
 
 
  
 
   
 
    
    
 
    
   
 
   
 
   
   
 
    
    
 
    
 
    
 
    
 
    
 
    
 
    
 
    
 
    
 
    
 
    
   
 
   
   
  
 
  
  
 

其中需要圆角背景shape_input_area.xml:

 
 
  
  
  
 

需要数字按钮的背景selector_gride.xml:

 
 
  
   
    
   
  
  
   
    
   
  
  
   
    
   
  
 

需要回退键背景selector_key_del.xml:

 
 
  
   
    
   
  
  
   
    
   
  
  
   
    
   
  
 

下面来完成我们的自定义控件PasswordView.Java:

public class PasswordView extends RelativeLayout implements View.onClickListener { 
 Context context; 
 
 private String strPassword;  //输入的密码 
 private TextView[] tvList;  //用数组保存6个TextView,为什么用数组? 
  //因为就6个输入框不会变了,用数组内存申请固定空间,比List省空间(自己认为) 
 private GridView gridView; //用GrideView布局键盘,其实并不是真正的键盘,只是模拟键盘的功能 
 private ArrayList> valueList; //有人可能有疑问,为何这里不用数组了? 
//因为要用Adapter中适配,用数组不能往adapter中填充 
 
 private ImageView imgCancel; 
 private TextView tvForget; 
 private int currentIndex = -1; //用于记录当前输入密码格位置 
 
 public PasswordView(Context context) { 
  this(context, null); 
 } 
 
 public PasswordView(Context context, AttributeSet attrs) { 
  super(context, attrs); 
  this.context = context; 
  View view = View.inflate(context, R.layout.layout_popup_bottom, null); 
   
  valueList = new ArrayList>(); 
  tvList = new TextView[6]; 
   
  imgCancel = (ImageView) view.findViewById(R.id.img_cancel); 
  imgCancel.setonClickListener(this); 
 
  tvForget = (TextView) findViewById(R.id.tv_forgetPwd); 
  tvForget.setonClickListener(this); 
   
  tvList[0] = (TextView) view.findViewById(R.id.tv_pass1); 
  tvList[1] = (TextView) view.findViewById(R.id.tv_pass2); 
  tvList[2] = (TextView) view.findViewById(R.id.tv_pass3); 
  tvList[3] = (TextView) view.findViewById(R.id.tv_pass4); 
  tvList[4] = (TextView) view.findViewById(R.id.tv_pass5); 
  tvList[5] = (TextView) view.findViewById(R.id.tv_pass6); 
 
  gridView = (GridView) view.findViewById(R.id.gv_keybord); 
 
  setView(); 
   
  addView(view);  //必须要,不然不显示控件 
 } 
 
 @Override 
 public void onClick(View v) { 
  switch (v.getId()) { 
   case R.id.img_cancel: 
    Toast.makeText(context, "Cancel", Toast.LENGTH_SHORT).show(); 
    break; 
   case R.id.tv_forgetPwd: 
    Toast.makeText(context, "Forget", Toast.LENGTH_SHORT).show(); 
    break; 
  } 
 } 
 
 private void setView() { 
   
  for (int i = 1; i < 13; i++) { 
   Map map = new HashMap(); 
   if (i < 10) { 
    map.put("name", String.valueOf(i)); 
   } else if (i == 10) { 
    map.put("name", ""); 
   } else if (i == 12) { 
    map.put("name", "<<-"); 
   } else if (i == 11) { 
    map.put("name", String.valueOf(0)); 
   } 
   valueList.add(map); 
  } 
 
  gridView.setAdapter(adapter); 
  gridView.setonItemClickListener(new AdapterView.onItemClickListener() { 
   @Override 
   public void onItemClick(AdapterView parent, View view, int position, long id) { 
    if (position < 11 && position != 9) { //点击0~9按钮 
     if (currentIndex >= -1 && currentIndex < 5) {  //判断输入位置————要小心数组越界 
      tvList[++currentIndex].setText(valueList.get(position).get("name")); 
     } 
    } else { 
     if (position == 11) {  //点击退格键 
      if (currentIndex - 1 >= -1) {  //判断是否删除完毕————要小心数组越界 
tvList[currentIndex--].setText(""); 
      } 
     } 
    } 
   } 
  }); 
 } 
 
 //设置监听方法,在第6位输入完成后触发 
 public void setonFinishInput(final onPasswordInputFinish pass) { 
  tvList[5].addTextChangedListener(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 (s.toString().length() == 1) { 
     strPassword = "";  //每次触发都要先将strPassword置空,再重新获取,避免由于输入删除再输入造成混乱 
     for (int i = 0; i < 6; i++) { 
      strPassword += tvList[i].getText().toString().trim(); 
     } 
     pass.inputFinish(); //接口中要实现的方法,完成密码输入完成后的响应逻辑 
    } 
   } 
  }); 
 } 
 
  
 public String getStrPassword() { 
  return strPassword; 
 } 
 
  
 public ImageView getCancelImageView() { 
  return imgCancel; 
 } 
 
  
 public TextView getForgetTextView() { 
  return tvForget; 
 } 
 
 //GrideView的适配器 
 baseAdapter adapter = new baseAdapter() { 
  @Override 
  public int getCount() { 
   return valueList.size(); 
  } 
 
  @Override 
  public Object getItem(int position) { 
   return valueList.get(position); 
  } 
 
  @Override 
  public long getItemId(int position) { 
   return position; 
  } 
 
  @Override 
  public View getView(int position, View convertView, ViewGroup parent) { 
   ViewHolder viewHolder; 
   if (convertView == null) { 
    convertView = View.inflate(context, R.layout.item_gride, null); 
    viewHolder = new ViewHolder(); 
    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){ 
    viewHolder.btnKey.setBackgroundResource(R.drawable.selector_key_del); 
    viewHolder.btnKey.setEnabled(false); 
   } 
   if(position == 11){ 
    viewHolder.btnKey.setBackgroundResource(R.drawable.selector_key_del); 
   } 
 
   return convertView; 
  } 
 }; 
 
  
 public final class ViewHolder { 
  public TextView btnKey; 
 } 
} 

自认为代码注释还是可以的。就是在实现过程中要注意数组的越界问题,在输入逻辑响应中要注意逻辑处理,也就是grideView的OnItemClickListener事件处理。其中用到自定义的接口OnPasswordInputFinish来实现输入完成的事件回掉:

 
public interface onPasswordInputFinish { 
 void inputFinish(); 
} 

还有就是Adapter中用到的每个按钮Item的布局item_gride.xml:

 
 
 
  
  
 

好了,到此我们的自定义控件——模仿支付宝6位支付密码输入控件就完成了,下边我们在Activity中用一下,检验一下效果:
我们在MianActivity中用用一下我们定义好的控件:

public class MainActivity extends Activity { 
 
 @Override 
 protected void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
   
   
  setContentView(R.layout.activity_main); 
 
  final PasswordView pwdView = (PasswordView) findViewById(R.id.pwd_view); 
   
  //添加密码输入完成的响应 
  pwdView.setonFinishInput(new onPasswordInputFinish() { 
   @Override 
   public void inputFinish() { 
    //输入完成后我们简单显示一下输入的密码 
    //也就是说——>实现你的交易逻辑什么的在这里写 
    Toast.makeText(MainActivity.this, pwdView.getStrPassword(), Toast.LENGTH_SHORT).show(); 
   } 
  }); 
   
   
  pwdView.getCancelImageView().setonClickListener(new View.onClickListener() { 
   @Override 
   public void onClick(View v) { 
    Toast.makeText(MainActivity.this, "Biu Biu Biu", Toast.LENGTH_SHORT).show(); 
   } 
  }); 
   
 
   
   
//  final PasswordView pwdView = new PasswordView(this); 
//  setContentView(pwdView); 
//  pwdView.setonFinishInput(new onPasswordInputFinish() { 
//   @Override 
//   public void inputFinish() { 
//    Toast.makeText(MainActivity.this, pwdView.getStrPassword(), Toast.LENGTH_SHORT).show(); 
//   } 
//  }); 
   
 } 
} 

在第一种方法中我们用到的布局文件:

 
 
 
  
 

更多内容请参考专题:Android密码使用教程

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/160342.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号