2011-09-26 69 views
3

我正在使用InputFilter类来创建支持数字分组的掩码EditText。例如,当用户插入“12345”时,我想在EditText中显示“12,345”。我怎样才能实现它?如何使用InputFilter实现数字分组输入掩码?

这是我的不完整代码:

 InputFilter IF = new InputFilter() { 
     @Override 
     public CharSequence filter(CharSequence source, int start, int end, 
       Spanned dest, int dstart, int dend) { 

      for (int i = start; i < end; i++) { 
       if (!Character.isLetterOrDigit(source.charAt(i))) { 
        return ""; 
       } 
      } 
      if (dest.length() > 0 && dest.length() % 3 == 0) 
      { 
       return "," + source; 
      } 
      return null; 
     } 
    }; 
    edtRadius.setFilters(new InputFilter[] { IF }); 

是否有实现这种输入掩码的任何其他方式?

回答

1

如果你还在搜索,我在最后一天遇到了这个问题,发现使用TextWatcher是最好的(仍然不是很好)选项。我必须将信用卡号码的数字分组。

someEditText.addTextChagedListener(new TextWatcher() 
{ 
    //According to the developer guide, one shall only edit the EditText's 
    //content in this function. 
    @Override 
    public void afterTextChanged(Editable text) 
    { 
     //You somehow need to access the EditText to remove this listener 
     //for the time of the changes made here. This is one way, but you 
     //can create a proper TextWatcher class and pass the EditText to 
     //its constructor, or have the EditText as a member of the class 
     //this code is running in (in the last case, you simply have to 
     //delete this line). 
     EditText someEditText = (EditText) findViewById(R.id.someEditText); 

     //Remove listener to prevent further call due to the changes we're 
     //about to make (TextWatcher is recursive, this function will be 
     //called again for every change you make, and in my experience, 
     //replace generates multiple ones, so a flag is not enough. 
     someEditText.removeTextChangedListener(this); 

     //Replace text with processed the processed string. 
     //FormatText is a function that takes a CharSequence (yes, you can 
     //pass the Editable directly), processes it the way you want, then 
     //returns the result as a String. 
     text.replace(0, text.length(), FormatText(text)); 

     //Place the listener back 
     someEditText.addTextChangedListener(this); 
    } 

    @Override 
    public void beforeTextChaged(CharSequence s, int start, int count, int after) 
    { 

    } 

    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) 
    { 

    } 
}); 

我的信用卡号码格式化功能是这样的:

String FormatText(CharSequence text) 
{ 
    StringBuilder formatted = new StringBuilder(); 

    int count = 0; 
    for (int i = 0; i < text.length(); ++i) 
    { 
     if (Character.isDigit(text.charAt(i))) 
     { 
      //You have to be careful here, only add extra characters before a 
      //user-typed character, otherwise the user won't be able to delete 
      //with backspace, since you put the extra character back immediately. 
      //However, this way, my solution would put a space at the start of 
      //the string that I don't want, hence the > check. 
      if (count % 4 == 0 && count > 0) 
       formatted.append(' '); 
      formatted.append(text.charAt(i)); 
      ++count; 
     } 
    } 

    return formatted.toString(); 
} 

您可能必须想到其他一些问题,因为该解决方案每次变更时居然改写的EditText的内容。例如,您应该避免处理自己插入的字符(这是isDigit检查的另一个原因)。

5

这是对@vincent响应的改进。它在格式为1234 5678 9190的格式中添加了删除空格的检查,所以当试图删除一个空格时,它只是将光标后退字符移动到空格前的数字。即使插入空格,它也会将光标保持在相同的相对位置。

mTxtCardNumber.addTextChangedListener(new TextWatcher() { 

     private boolean spaceDeleted; 

     public void onTextChanged(CharSequence s, int start, int before, int count) { 
     } 

     public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
      // check if a space was deleted 
      CharSequence charDeleted = s.subSequence(start, start + count); 
      spaceDeleted = " ".equals(charDeleted.toString()); 
     } 

     public void afterTextChanged(Editable editable) { 
      // disable text watcher 
      mTxtCardNumber.removeTextChangedListener(this); 

      // record cursor position as setting the text in the textview 
      // places the cursor at the end 
      int cursorPosition = mTxtCardNumber.getSelectionStart(); 
      String withSpaces = formatText(editable); 
      mTxtCardNumber.setText(withSpaces); 
      // set the cursor at the last position + the spaces added since the 
      // space are always added before the cursor 
      mTxtCardNumber.setSelection(cursorPosition + (withSpaces.length() - editable.length())); 

      // if a space was deleted also deleted just move the cursor 
      // before the space 
      if (spaceDeleted) { 
       mTxtCardNumber.setSelection(mTxtCardNumber.getSelectionStart() - 1); 
       spaceDeleted = false; 
      } 

      // enable text watcher 
      mTxtCardNumber.addTextChangedListener(this); 
     } 

     private String formatText(CharSequence text) 
     { 
      StringBuilder formatted = new StringBuilder(); 
      int count = 0; 
      for (int i = 0; i < text.length(); ++i) 
      { 
       if (Character.isDigit(text.charAt(i))) 
       { 
        if (count % 4 == 0 && count > 0) 
         formatted.append(" "); 
        formatted.append(text.charAt(i)); 
        ++count; 
       } 
      } 
      return formatted.toString(); 
     } 
    }); 
0

使用简单的函数:

public String digit_grouping(String in_digit){ 

    String res = ""; 

    final int input_len = in_digit.length(); 
    for(int i=0 ; i< input_len ; i++) 
    { 

     if((i % 3 == 0) && i > 0) 
      res = "," + res; 

     res = in_digit.charAt(input_len - i - 1) + res; 

    } 

    return res; 
}