查看: 561|回复: 0

[Android教程] Android 实现仿支付宝的密码均分输入框

发表于 2017-11-28 08:00:01

Android 仿支付宝的密码均分输入框

此为安卓项目,通过重绘edittext进行文字的均分排布。

直接贴上代码:

  1. package com.xxx.xxx;
  2. import android.content.Context;
  3. import android.graphics.Canvas;
  4. import android.graphics.Color;
  5. import android.graphics.Paint;
  6. import android.graphics.Rect;
  7. import android.text.Editable;
  8. import android.text.Selection;
  9. import android.text.TextWatcher;
  10. import android.util.AttributeSet;
  11. import android.view.ViewGroup;
  12. import android.widget.EditText;
  13. /**
  14. * 此控件为均分输入框控件
  15. * 使用说明:XML文件中设置好文字大小,设置好宽度。高度使用wrap_content更佳,亦可设置固定高度
  16. * (随着输入的行数变化会导致高度成倍增加)
  17. * 允许设置每行显示的文字个数
  18. * 允许设置最多显示多少行
  19. * 允许设置密码符显示
  20. * 允许设置多行输入
  21. *
  22. * Created by yueer on 2015/10/22.
  23. */
  24. public class ExcelEditView extends EditText {
  25. private int mMaxLength = 6; //一行显示的最大字符数
  26. private int mColorId = Color.BLACK; //字体颜色
  27. private boolean isPassword = false; //是否需要显示密码符
  28. private float mHeight = 0.0f; //默认情况的高度
  29. private int mMaxLine = 0; //最大的行数:如果为0,---表示支持多行输入 不为0,--则为该行
  30. public ExcelEditView(Context context){
  31. super(context);
  32. init();
  33. }
  34. public ExcelEditView(Context context, AttributeSet set){
  35. super(context, set);
  36. init();
  37. }
  38. private void init(){
  39. this.addTextChangedListener(new TextWatcher() {
  40. @Override
  41. public void beforeTextChanged(CharSequence s, int start, int count, int after) {
  42. }
  43. @Override
  44. public void onTextChanged(CharSequence s, int start, int before, int count) {
  45. // TODO Auto-generated method stub
  46. Editable editable = ExcelEditView.this.getText();
  47. int len = editable.length();
  48. if(mMaxLine > 0 && len > mMaxLength*mMaxLine)
  49. {
  50. int selEndIndex = Selection.getSelectionEnd(editable);
  51. String str = editable.toString();
  52. String newStr = str.substring(0,mMaxLength*mMaxLine);
  53. ExcelEditView.this.setText(newStr);
  54. editable = ExcelEditView.this.getText();
  55. //新字符串的长度
  56. int newLen = editable.length();
  57. //旧光标位置超过字符串长度
  58. if(selEndIndex > newLen)
  59. {
  60. selEndIndex = editable.length();
  61. }
  62. //设置新光标所在的位置
  63. Selection.setSelection(editable, selEndIndex);
  64. }
  65. }
  66. @Override
  67. public void afterTextChanged(Editable s) {
  68. }
  69. });
  70. }
  71. public void setIsPassword(boolean isPassword){
  72. this.isPassword = isPassword;
  73. }
  74. public void setmMaxLine(int line){
  75. this.mMaxLine = line;
  76. }
  77. public void setmMaxLength(int leng){
  78. this.mMaxLength = leng;
  79. }
  80. @Override
  81. public void setTextColor(int color) {
  82. super.setTextColor(color);
  83. mColorId = color;
  84. }
  85. @Override
  86. protected void onDraw(Canvas canvas) {
  87. char[] txt = this.getText().toString().toCharArray(); //取出字符数组
  88. int txtLine = getLineFromCharArray(txt); //计算有多少行
  89. if (mMaxLine > 0 && txtLine > mMaxLine){ //进行行数的上限处理
  90. txtLine = mMaxLine;
  91. }
  92. if (this.isPassword){ //密码符的转义
  93. for (int i=0; i<txt.length; i++){
  94. txt[i] = '*';
  95. }
  96. }
  97. if (mHeight == 0){ //获取最初控件的高度
  98. mHeight = this.getHeight();
  99. }
  100. float width = this.getWidth();
  101. float height = mHeight * txtLine;
  102. ViewGroup.LayoutParams params = this.getLayoutParams();
  103. params.height = (int)height;
  104. this.setLayoutParams(params); //动态设置控件高度
  105. float per = width / (mMaxLength+1); //宽度等分
  106. float perHeight = height / (txtLine + 1); //高度等分
  107. Paint countPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);
  108. countPaint.setColor(mColorId);
  109. countPaint.setTextSize(this.getTextSize());
  110. countPaint.setTypeface(this.getTypeface());
  111. countPaint.setTextAlign(Paint.Align.CENTER);
  112. Rect textBounds = new Rect();
  113. String numberStr = "1";
  114. countPaint.getTextBounds(numberStr, 0, numberStr.length(), textBounds);//get text bounds, that can get the text width and height
  115. float textHeight = (float)(textBounds.bottom - textBounds.top);
  116. float textWidth = (float)(textBounds.right = textBounds.left); //计算该控件中能够显示的单一文字的高度和宽度
  117. for (int line = 0; line < txtLine; line++) {
  118. for (int i = 0; i < mMaxLength && txt.length > (i+line*mMaxLength); i++) {
  119. canvas.drawText(String.valueOf(txt[i+line*mMaxLength]), (i + 1) * per - textWidth, perHeight * (line + 1) + textHeight / 2, countPaint); //进行绘制
  120. }
  121. }
  122. }
  123. private int getLineFromCharArray(char[] txt){
  124. int line = ((txt.length - 1) / mMaxLength) + 1;
  125. return line;
  126. }
  127. }
复制代码

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!



回复

使用道具 举报

关闭

站长推荐上一条 /1 下一条