【问题标题】:android format edittext to display spaces after every 4 charactersandroid格式edittext每4个字符后显示空格
【发布时间】:2021-03-29 22:31:57
【问题描述】:

Android - 我想将用户输入的数字输入 EditText - 它需要用空格分隔 - 每 4 个字符。 示例:123456781234 -> 1234 5678 1234

这仅用于视觉目的。但是我需要不带空格的字符串以供进一步使用。

我能做到这一点的最简单方法是什么?

【问题讨论】:

    标签: android android-edittext


    【解决方案1】:

    这是信用卡的编辑文本吗?
    首先创建计数变量

    int count = 0;
    

    然后把它放在你的 oncreate(activity) / onviewcreated(fragment) 中

    ccEditText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start,
                                      int count, int after) { /*Empty*/}
    
        @Override
        public void onTextChanged(CharSequence s, int start, int before,
                                  int count) { /*Empty*/ }
    
        @Override
        public void afterTextChanged(Editable s) {
    
            int inputlength = ccEditText.getText().toString().length();
    
            if (count <= inputlength && inputlength == 4 ||
                    inputlength == 9 || inputlength == 14)){
    
                ccEditText.setText(ccEditText.getText().toString() + " ");
    
                int pos = ccEditText.getText().length();
                ccEditText.setSelection(pos);
    
            } else if (count >= inputlength && (inputlength == 4 ||
                    inputlength == 9 || inputlength == 14)) {
                ccEditText.setText(ccEditText.getText().toString()
                        .substring(0, ccEditText.getText()
                                .toString().length() - 1));
    
                int pos = ccEditText.getText().length();
                ccEditText.setSelection(pos);
            }
            count = ccEditText.getText().toString().length();
        }
    });
    

    【讨论】:

      【解决方案2】:

      正如@waqas 指出的那样,如果您的目标是在用户键入数字时实现这一点,则需要使用 TextWatcher。这是实现空间的一种潜在方法:

      StringBuilder s;
      s = new StringBuilder(yourTxtView.getText().toString());
      
      for(int i = 4; i < s.length(); i += 5){
          s.insert(i, " ");
      }
      yourTxtView.setText(s.toString());
      

      当您需要获取不带空格的字符串时,请执行以下操作:

      String str = yourTxtView.getText().toString().replace(" ", "");
      

      【讨论】:

        【解决方案3】:

        有一种更简单的方法可以实现这一点:

        editText.doAfterTextChanged { text ->
            val formattedText = text.toString().replace(" ", "").chunked(4).joinToString(" ")
            if (formattedText != text.toString()) {
                editText.setText(formattedText)
            }
        }
        

        当你想得到没有空格的文本时,只需这样做:

        editText.text.toString().replace(" ","")
        

        【讨论】:

        • 那不行。当我输入“123456789012”时,我得到9012 5678 1234,应该类似于1234 5678 9012
        【解决方案4】:

        您需要使用TextWatcher 来实现视觉目的空间。

        并使用任何简单的按空格分割字符串逻辑将其加入或循环遍历每个字符的整个字符串,并从字符串中消除(char) 32

        【讨论】:

          【解决方案5】:

          我创建了一个封装给定行为的类。

          /**
           * Custom [TextWatcher] class that appends a given [separator] for every [interval].
           */
          abstract class SeparatorTextWatcher(
              private val separator: Char,
              private val interval: Int
          ) : TextWatcher {
          
              private var dirty = false
              private var isDelete = false
          
              override fun afterTextChanged(editable: Editable?) {
                  if (dirty) return
          
                  dirty = true
                  val text = editable.toString().handleSeparator()
                  onAfterTextChanged(text)
                  dirty = false
              }
          
              override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
                  // Empty
              }
          
              override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                  isDelete = before != 0
              }
          
              private fun String.handleSeparator(): String {
                  val stringBuilder = StringBuilder(this)
          
                  if (length > 0 && length.rem(interval + 1) == 0) {
                      if (isDelete) {
                          stringBuilder.deleteCharAt(length - 1)
                      } else {
                          stringBuilder.insert(length - 1, separator)
                      }
                  }
          
                  return stringBuilder.toString()
              }
          
              /**
               * Subclasses must implement this method to get the formatted text.
               */
              abstract fun onAfterTextChanged(text: String)
          }
          

          这是一个关于如何使用它的sn-p:

          editText.addTextChangedListener(object : SeparatorTextWatcher(' ', 4) {
                      override fun onAfterTextChanged(text: String) {
                          editText.run {
                              setText(text)
                              setSelection(text.length)
                          }
                      }
                  })
          

          【讨论】:

          • 在edittext中粘贴文本时无法正常工作。
          【解决方案6】:

          文本格式为 000 000 0000

          android edittext textwatcher format phone number like xxx-xxx-xx-xx

          public class PhoneNumberTextWatcher implements TextWatcher {
          
          private static final String TAG = PhoneNumberTextWatcher.class
                  .getSimpleName();
          private EditText edTxt;
          private boolean isDelete;
          
          public PhoneNumberTextWatcher(EditText edTxtPhone) {
              this.edTxt = edTxtPhone;
              edTxt.setOnKeyListener(new View.OnKeyListener() {
          
                  @Override
                  public boolean onKey(View v, int keyCode, KeyEvent event) {
                      if (keyCode == KeyEvent.KEYCODE_DEL) {
                          isDelete = true;
                      }
                      return false;
                  }
              });
          }
          
          public void onTextChanged(CharSequence s, int start, int before, int count) {
          }
          
          public void beforeTextChanged(CharSequence s, int start, int count,
                                        int after) {
          }
          
          public void afterTextChanged(Editable s) {
          
              if (isDelete) {
                  isDelete = false;
                  return;
              }
              String val = s.toString();
              String a = "";
              String b = "";
              String c = "";
              if (val != null && val.length() > 0) {
                  val = val.replace(" ", "");
                  if (val.length() >= 3) {
                      a = val.substring(0, 3);
                  } else if (val.length() < 3) {
                      a = val.substring(0, val.length());
                  }
                  if (val.length() >= 6) {
                      b = val.substring(3, 6);
                      c = val.substring(6, val.length());
                  } else if (val.length() > 3 && val.length() < 6) {
                      b = val.substring(3, val.length());
                  }
                  StringBuffer stringBuffer = new StringBuffer();
                  if (a != null && a.length() > 0) {
                      stringBuffer.append(a);
                      if (a.length() == 3) {
                          stringBuffer.append(" ");
                      }
                  }
                  if (b != null && b.length() > 0) {
                      stringBuffer.append(b);
                      if (b.length() == 3) {
                          stringBuffer.append(" ");
                      }
                  }
                  if (c != null && c.length() > 0) {
                      stringBuffer.append(c);
                  }
                  edTxt.removeTextChangedListener(this);
                  edTxt.setText(stringBuffer.toString());
                  edTxt.setSelection(edTxt.getText().toString().length());
                  edTxt.addTextChangedListener(this);
              } else {
                  edTxt.removeTextChangedListener(this);
                  edTxt.setText("");
                  edTxt.addTextChangedListener(this);
              }
          
          }
          }
          

          【讨论】:

            【解决方案7】:

            遵循 DRY 原则的@Ario 答案的更简洁版本:

            private int prevCount = 0;
            private boolean isAtSpaceDelimiter(int currCount) {
                return currCount == 4 || currCount == 9 || currCount == 14;
            }
            
            private boolean shouldIncrementOrDecrement(int currCount, boolean shouldIncrement) {
                if (shouldIncrement) {
                    return prevCount <= currCount && isAtSpaceDelimiter(currCount);
                } else {
                    return prevCount > currCount && isAtSpaceDelimiter(currCount);
                }
            }
            
            private void appendOrStrip(String field, boolean shouldAppend) {
                StringBuilder sb = new StringBuilder(field);
                if (shouldAppend) {
                    sb.append(" ");
                } else {
                    sb.setLength(sb.length() - 1);
                }
                cardNumber.setText(sb.toString());
                cardNumber.setSelection(sb.length());
            }
            
            ccEditText.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) {
                    String field = editable.toString();
                    int currCount = field.length();
            
                    if (shouldIncrementOrDecrement(currCount, true)){
                        appendOrStrip(field, true);
                    } else if (shouldIncrementOrDecrement(currCount, false)) {
                        appendOrStrip(field, false);
                    }
                    prevCount = cardNumber.getText().toString().length(); 
                } 
            }); 
            

            【讨论】:

              【解决方案8】:

              我在这里搜索了很多,这是 kotlin 中卡片的完整代码

                yourEditText.addTextChangedListener(object : TextWatcher {
                      private val TOTAL_SYMBOLS = 19 // size of pattern 0000-0000-0000-0000
                      private val TOTAL_DIGITS = 16 // max numbers of digits in pattern: 0000 x 4
                      private val DIVIDER_MODULO =
                          5 // means divider position is every 5th symbol beginning with 1
                      private val DIVIDER_POSITION =
                          DIVIDER_MODULO - 1 // means divider position is every 4th symbol beginning with 0
                      private val DIVIDER = ' '
                      override fun beforeTextChanged(
                          s: CharSequence,
                          start: Int,
                          count: Int,
                          after: Int
                      ) { // noop
                      }
              
                      override fun onTextChanged(
                          s: CharSequence,
                          start: Int,
                          before: Int,
                          count: Int
                      ) { // noop
                      }
              
                      override fun afterTextChanged(s: Editable) {
                          if (!isInputCorrect(s, TOTAL_SYMBOLS, DIVIDER_MODULO, DIVIDER)) {
              
                              var repl = buildCorrectString(
                                      getDigitArray(s, TOTAL_DIGITS),
                              DIVIDER_POSITION,
                              DIVIDER
                              )
              
                              yourEditText.clearFocus();
                              yourEditText.setText(repl);
                             yourEditText.requestFocus();
                              yourEditText.setSelection(repl!!.length);
              
                          }
                      }
              
                      private fun isInputCorrect(
                          s: Editable,
                          totalSymbols: Int,
                          dividerModulo: Int,
                          divider: Char
                      ): Boolean {
                          var isCorrect =
                              s.length <= totalSymbols // check size of entered string
                          for (i in 0 until s.length) { // check that every element is right
                              isCorrect = if (i > 0 && (i + 1) % dividerModulo == 0) {
                                  isCorrect and (divider == s[i])
                              } else {
                                  isCorrect and Character.isDigit(s[i])
                              }
                          }
                          return isCorrect
                      }
              
                      private fun buildCorrectString(
                          digits: CharArray,
                          dividerPosition: Int,
                          divider: Char
                      ): String? {
                          val formatted = StringBuilder()
                          for (i in digits.indices) {
                              if (digits[i] != '\u0000') {
                                  formatted.append(digits[i])
                                  if (i > 0 && i < digits.size - 1 && (i + 1) % dividerPosition == 0) {
                                      formatted.append(divider)
                                  }
                              }
                          }
                          return formatted.toString()
                      }
              
                      private fun getDigitArray(s: Editable, size: Int): CharArray {
                        val digits = CharArray(size)
                          var index = 0
                          var i = 0
                          while (i < s.length && index < size) {
                              val current = s[i]
                              if (Character.isDigit(current)) {
                                  digits[index] = current
                                  index++
                              }
                              i++
                          }
                          return digits
                      }
                  })
              }
              

              【讨论】:

                【解决方案9】:

                这里有一个小帮助功能。对于您的示例,您可以使用

                addPadding(" ", "123456781234", 4);

                /**
                 * @brief Insert arbitrary string at regular interval into another string 
                 * 
                 * @param t String to insert every 'num' characters
                 * @param s String to format
                 * @param num Group size
                 * @return
                 */
                private String addPadding(String t, String s, int num) {
                    StringBuilder retVal;
                
                    if (null == s || 0 >= num) {
                        throw new IllegalArgumentException("Don't be silly");
                    }
                
                    if (s.length() <= num) {
                        //String to small, do nothing
                        return s;
                    }
                
                    retVal = new StringBuilder(s);
                
                    for(int i = retVal.length(); i > 0; i -= num){
                        retVal.insert(i, t);
                    }
                    return retVal.toString();
                }
                

                【讨论】:

                  【解决方案10】:

                  在键入时更改实时文本有些困难。我们应该处理以下问题。

                  一个。光标位置 湾。我们应该允许用户删除输入的文本。

                  以下代码处理这两个问题。

                  1. 将 TextWatcher 添加到 EditText,并从“afterTextchanged()”中获取文本并编写您的逻辑

                    字符串 str=""; int strOldlen=0;

                        @Override
                                public void afterTextChanged(Editable s) {
                    
                       str = edtAadharNumber.getText().toString();
                                    int strLen = str.length();
                    
                    
                                    if(strOldlen<strLen) {
                    
                                        if (strLen > 0) {
                                            if (strLen == 4 || strLen == 9) {
                    
                                                str=str+" ";
                    
                                                edtAadharNumber.setText(str);
                                                edtAadharNumber.setSelection(edtAadharNumber.getText().length());
                    
                                            }else{
                    
                                                if(strLen==5){
                                                    if(!str.contains(" ")){
                                                     String tempStr=str.substring(0,strLen-1);
                                                        tempStr +=" "+str.substring(strLen-1,strLen);
                                                        edtAadharNumber.setText(tempStr);
                                                        edtAadharNumber.setSelection(edtAadharNumber.getText().length());
                                                    }
                                                }
                                                if(strLen==10){
                                                    if(str.lastIndexOf(" ")!=9){
                                                        String tempStr=str.substring(0,strLen-1);
                                                        tempStr +=" "+str.substring(strLen-1,strLen);
                                                        edtAadharNumber.setText(tempStr);
                                                        edtAadharNumber.setSelection(edtAadharNumber.getText().length());
                                                    }
                                                }
                                                strOldlen = strLen;
                                            }
                                        }else{
                                            return;
                                        }
                    
                                    }else{
                                        strOldlen = strLen;
                    
                    
                                        Log.i("MainActivity ","keyDel is Pressed ::: strLen : "+strLen+"\n old Str Len : "+strOldlen);
                                    }
                    
                                }
                    }
                    
                  2. 在这里,我尝试为每四个字符添加空格。添加第一个空格后,文本的长度为5。所以下一个空格是在9个字符之后。

                    如果 (strLen== 4||strLen==9)

                    1. 这里的另一个问题是光标位置,一旦你修改了edittext的文本,光标就会移动到第一位。所以我们需要手动设置光标。

                    edtAadharNumber.setSelection(edtAadharNumber.getText().length());

                    1. 我的文本长度只有 12 个字符。所以我在做手动计算,如果你的文本是动态的,那么你编写动态逻辑。

                  【讨论】:

                  • 当我尝试删除文本时,它一次只删除 4 个字符。
                  【解决方案11】:

                  如果有人还在寻找答案,请查看format-edit-text library

                  public class MainActivity extends AppCompatActivity {
                  
                      @Override
                      protected void onCreate(Bundle savedInstanceState) {
                          super.onCreate(savedInstanceState);
                          setContentView(R.layout.activity_main);
                  
                          final FormatEditText editText1 = findViewById(R.id.edit_text_1);
                          editText1.setFormat("---- ---- ---- ----");
                      }
                  }
                  

                  参考 https://stackoverflow.com/a/59742478/1679946

                  【讨论】:

                    【解决方案12】:

                    如果您使用数据绑定添加

                    android:afterTextChanged="@{handler::afterTextChanged}"    
                    

                    在EditText和afterTextChanged函数中如下:

                    fun afterTextChanged(s: Editable) {
                        if (s.length > 0 && s.length % 5 === 0) {
                            val c: Char = s.get(s.length - 1)
                            if (space === c) {
                                s.delete(s.length - 1, s.length)
                            }
                        }
                        // Insert char where needed.
                        if (s.length > 0 && s.length % 5 === 0) {
                            val c: Char = s.get(s.length - 1)
                            // Only if its a digit where there should be a space we insert a space
                            if (Character.isDigit(c) && TextUtils.split(
                                    s.toString(),
                                    space.toString()
                                ).size <= 3
                            ) {
                                s.insert(s.length - 1, space.toString())
                            }
                        }
                    }
                    

                    这样添加空格

                     private val space: Char = ' '
                    

                    如果您使用 inputType="numberDigit" 这将禁用 '-' 和 ' ' 字符,所以我建议使用 inputType="phone"

                    【讨论】:

                    • 即使我们尝试在中间添加删除一个字符并代表添加一些新字符,这个逻辑是否有效
                    【解决方案13】:

                    假设您知道字符串的最终长度,您可以这样实现TextWatcher

                    override fun setUp(view: View?) {
                    
                        editText.addTextChangedListener(object : TextWatcher{
                            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
                            }
                    
                            override fun onTextChanged(p0: CharSequence, p1: Int, p2: Int, p3: Int) {
                                if(p2 == 0 && (p0.length == 4 || p0.length == 9 || p0.length == 14))
                                    editText.append(" ")
                            }
                    
                            override fun afterTextChanged(p0: Editable?) {
                            }
                        })
                    

                    您只需在每个 4 位数字块中添加一个空格。 p2 == 0是为了保证用户没有删除,否则他/她会得到库存。

                    代码在 Kotlin 中,你可以用 Java 完全一样的方式来做。

                    【讨论】:

                      【解决方案14】:

                      简单回答

                          YourEditText.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) {
                      
                                  int len=s.toString().length();
                      
                                  if (before == 0 && (len == 4 || len == 9 || len == 14 ))
                                      YourEditText.append(" ");
                              }
                      
                              @Override
                              public void afterTextChanged(Editable s) {
                      
                      
                              }
                          });
                      

                      【讨论】:

                      • 当用户按下返回按钮时,空间被删除用户再次可以输入数字。
                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2014-07-30
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多