Android支付密码输入框【转】

来自:http://blog.csdn.net/ywl5320/article/details/52003691

现在很多应用都会集成支付功能,不管是直接调用支付SDK还是自己平台的虚拟货币,支付密码都是很重要的。一般的应用会直接使用Edittext作为密码输入框,这个看着就有点low了,高大上一点的就会自定义一个支付界面,然后输入效果也会有相应的设计,比如我们看到的支付宝和微信支付就是这样的。因为常用所以我也就简单的写了一个类似的支付密码输入控件,望以后不再纠结于此事,哈哈哈,先来张效果图:


控件就是这样的,具体和怎样的支付界面或对话框搭配,就可以灵活使用了。


编程写代码的快慢和Bug的多少都取决于编程思路和思想,所谓编程的思路想法才是最重要的,即:算法是灵魂。所以我们先说说实现思想是怎么回事,当思想懂了,写代码就可以有一千种方式了。

一、实现思想如下:

分析效果图我们可以发现要能输入类容还要得到内容的值,所以首先得有Edittext。第一种尝试:密码个数是多少个,就写多少个Edittext,然后监听每个的值,最后组合到一起就是输入的密码。这个方式可以简单的实现顺序输入效果,但是就没有那么灵活了,会考虑当前输入框前后输入框的值是否有,是否需要跳转指针等等麻烦的事,而且代码也比较多,所以这种方式就pass掉了;第二种尝试:就是一个Edittext,然后在它上面覆盖密码个数的TextView,随时监听Edittext的内容变化实时反馈到TextView中,就可以达到这种效果了,而且只有一个Edittext,长按退格键可以删除完内容,还可以直接清空类容都很方便。这里有个技巧就是,输入框Edittext的大小应该和TextView组合起来的整体大小一致,点击效果才能更完美,然后Edittext的字体大小应该尽量小(0或者1),才能保证每次获取焦点时都是在内容最末尾处。这样就可以实现这种支付密码效果了。

二、封装过程

思路大家已经知道了,根据思路来如果每次用xml布局的话,那还是很麻烦的,要写那么多Textview和布局,这是我们不能忍受的,贴别是应用中多个地方都用到了支付功能,那就GG了。所以我把这些操作都封装到了一个控件里面,然后暴露出相应的方法来设置属性(这里不是很全,可根据自己的需求添加相应的属性方法来达到自己的效果),使用时就当做一个简单的控件使用就行(本人不是很喜欢自定义属性,感觉有点拖泥带水的,所以都是用方法来实现的)。

(1)因为有控件重叠效果,所以首先集成RelativeLayout来达到这个效果。

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * Created by ywl on 2016/7/10. 
  3.  */  
  4. public class PayPwdEditText extends RelativeLayout{  
  5.   
  6.     private EditText editText; //文本编辑框  
  7.     private Context context;  
  8.   
  9.     private LinearLayout linearLayout; //文本密码的文本  
  10.     private TextView[] textViews; //文本数组  
  11.   
  12.     private int pwdlength = 6//密码长度, 默认6  
  13.   
  14.     private OnTextFinishListener onTextFinishListener;  
  15.   
  16.   
  17.     public PayPwdEditText(Context context) {  
  18.         this(context, null);  
  19.     }  
  20.   
  21.     public PayPwdEditText(Context context, AttributeSet attrs) {  
  22.         this(context, attrs, 0);  
  23.     }  
  24.   
  25.     public PayPwdEditText(Context context, AttributeSet attrs, int defStyleAttr) {  
  26.         super(context, attrs, defStyleAttr);  
  27.         this.context = context;  
  28.     }  
  29. }  
(2)分析要用到的属性,有密码框的背景布局、密码长度、每个密码直接的分割线宽度和颜色、密码字体颜色和大小(还可以密码设置显示的字符效果,这里没有添加,使用的默认效果)

(3)初始化Edittext

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.      * 初始化编辑框 
  3.      * @param bgcolor 
  4.      */  
  5.     private void initEdit(int bgcolor)  
  6.     {  
  7.         editText = new EditText(context);  
  8.         editText.setBackgroundResource(bgcolor);  
  9.         editText.setCursorVisible(false);  
  10.         editText.setTextSize(0);  
  11.         editText.setInputType(InputType.TYPE_NUMBER_VARIATION_PASSWORD | InputType.TYPE_CLASS_NUMBER);  
  12.         editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(pwdlength)});  
  13.         editText.addTextChangedListener(new TextWatcher() {  
  14.             @Override  
  15.             public void beforeTextChanged(CharSequence s, int start, int count, int after) {  
  16.                 Editable etext = editText.getText();  
  17.                 Selection.setSelection(etext, etext.length());  
  18.             }  
  19.   
  20.             @Override  
  21.             public void onTextChanged(CharSequence s, int start, int before, int count) {  
  22.   
  23.             }  
  24.   
  25.             @Override  
  26.             public void afterTextChanged(Editable s) {  
  27.                 initDatas(s);  
  28.                 if(s.length() == pwdlength)  
  29.                 {  
  30.                     if(onTextFinishListener != null)  
  31.                     {  
  32.                         onTextFinishListener.onFinish(s.toString().trim());  
  33.                     }  
  34.                 }  
  35.             }  
  36.         });  
  37.         LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);  
  38.         lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);  
  39.         addView(editText, lp);  
  40.   
  41.     }  
这里可以对输入框的类型进行定制,只能输入数字还是数字字母混合等,然后监听每次输入的类容,并添加回调接口,方便使用时得到数据。

(4)初始化TextView显示框

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.      * @param bgcolor 背景drawable 
  3.      * @param pwdlength 密码长度 
  4.      * @param slpilinewidth 分割线宽度 
  5.      * @param splilinecolor 分割线颜色 
  6.      * @param pwdcolor 密码字体颜色 
  7.      * @param pwdsize 密码字体大小 
  8.      */  
  9.     public void initShowInput(int bgcolor, int pwdlength, float slpilinewidth, int splilinecolor, int pwdcolor, int pwdsize)  
  10.     {  
  11.         //添加密码框父布局  
  12.         linearLayout = new LinearLayout(context);  
  13.         linearLayout.setBackgroundResource(bgcolor);  
  14.         LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);  
  15.         linearLayout.setLayoutParams(layoutParams);  
  16.         linearLayout.setOrientation(LinearLayout.HORIZONTAL);  
  17.         addView(linearLayout);  
  18.   
  19.         //添加密码框  
  20.         textViews = new TextView[pwdlength];  
  21.         LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LayoutParams.MATCH_PARENT);  
  22.         params.weight = 1;  
  23.         params.gravity = Gravity.CENTER;  
  24.   
  25.         LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(dip2px(context, slpilinewidth),LayoutParams.MATCH_PARENT);  
  26.         for(int i = 0; i < textViews.length; i++)  
  27.         {  
  28.             final int index = i;  
  29.             TextView textView = new TextView(context);  
  30.             textView.setGravity(Gravity.CENTER);  
  31.             textViews[i] = textView;  
  32.             textViews[i].setTextSize(pwdsize);  
  33.             textViews[i].setTextColor(context.getResources().getColor(pwdcolor));  
  34.             textViews[i].setInputType(InputType.TYPE_NUMBER_VARIATION_PASSWORD | InputType.TYPE_CLASS_NUMBER);  
  35.             linearLayout.addView(textView, params);  
  36.   
  37.   
  38.             if(i < textViews.length - 1)  
  39.             {  
  40.                 View view = new View(context);  
  41.                 view.setBackgroundColor(context.getResources().getColor(splilinecolor));  
  42.                 linearLayout.addView(view, params2);  
  43.             }  
  44.         }  
  45.     }  
这个也是初始化TextView的显示效果,然后根据密码长度动态添加到布局中,并保存每个TextView的引用,方便以后对它门进行操作。

(5)然后是根据Edittext的输入内容设置Textview的值

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.      * 根据输入字符,显示密码个数 
  3.      * @param s 
  4.      */  
  5.     public void initDatas(Editable s)  
  6.     {  
  7.         if(s.length() > 0)  
  8.         {  
  9.             int length = s.length();  
  10.             for(int i = 0; i < pwdlength; i++)  
  11.             {  
  12.                 if(i < length)  
  13.                 {  
  14.                     for(int j = 0; j < length; j++)  
  15.                     {  
  16.                         char ch = s.charAt(j);  
  17.                         textViews[j].setText(String.valueOf(ch));  
  18.                     }  
  19.                 }  
  20.                 else  
  21.                 {  
  22.                     textViews[i].setText("");  
  23.                 }  
  24.             }  
  25.         }  
  26.         else  
  27.         {  
  28.             for(int i = 0; i < pwdlength; i++)  
  29.             {  
  30.                 textViews[i].setText("");  
  31.             }  
  32.         }  
  33.     }  
这个方法添加到Edittext的TextWatcher监听中即可,就能动态显示密码效果了。

核心思路和实现就是这样的,然后提供一个初始化入口:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.      * @param bgdrawable 背景drawable 
  3.      * @param pwdlength 密码长度 
  4.      * @param splilinewidth 分割线宽度 
  5.      * @param splilinecolor 分割线颜色 
  6.      * @param pwdcolor 密码字体颜色 
  7.      * @param pwdsize 密码字体大小 
  8.      */  
  9.     public void initStyle(int bgdrawable, int pwdlength, float splilinewidth, int splilinecolor, int pwdcolor, int pwdsize)  
  10.     {  
  11.         this.pwdlength = pwdlength;  
  12.         initEdit(bgdrawable);  
  13.         initShowInput(bgdrawable, pwdlength, splilinewidth, splilinecolor, pwdcolor, pwdsize);  
  14.     }  


其他属性方法如下:


[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.      * 是否显示明文 
  3.      * @param showPwd 
  4.      */  
  5.     public void setShowPwd(boolean showPwd) {  
  6.         int length = textViews.length;  
  7.         for(int i = 0; i < length; i++) {  
  8.             if (showPwd) {  
  9.                 textViews[i].setTransformationMethod(PasswordTransformationMethod.getInstance());  
  10.             } else {  
  11.                 textViews[i].setTransformationMethod(HideReturnsTransformationMethod.getInstance());  
  12.             }  
  13.         }  
  14.     }  
  15.   
  16.     /** 
  17.      * 设置显示类型 
  18.      * @param type 
  19.      */  
  20.     public void setInputType(int type)  
  21.     {  
  22.         int length = textViews.length;  
  23.         for(int i = 0; i < length; i++) {  
  24.             textViews[i].setInputType(type);  
  25.         }  
  26.     }  
  27.   
  28.     /** 
  29.      * 清除文本框 
  30.      */  
  31.     public void clearText()  
  32.     {  
  33.         editText.setText("");  
  34.         for(int i = 0; i < pwdlength; i++)  
  35.         {  
  36.             textViews[i].setText("");  
  37.         }  
  38.     }  
  39.   
  40.     public void setOnTextFinishListener(OnTextFinishListener onTextFinishListener) {  
  41.         this.onTextFinishListener = onTextFinishListener;  
  42.     }  
  43. /** 
  44.         得到输入内容 
  45.     */  
  46.     public String getPwdText()  
  47.     {  
  48.         if(editText != null)  
  49.             return editText.getText().toString().trim();  
  50.         return "";  
  51.     }  
  52.   
  53.     public static int dip2px(Context context, float dipValue) {  
  54.         final float scale = context.getResources().getDisplayMetrics().density;  
  55.         return (int) (dipValue * scale + 0.5f);  
  56.     }  
  57.   
  58.     public interface OnTextFinishListener  
  59.     {  
  60.         void onFinish(String str);  
  61.     }  
这样就全部写完了,还是不多是吧,哈哈哈。

项目源码免费下载地址:

1、CSDN:PayPwdEditText

2、Github:PayPwdEditText

欢迎下载和start

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值