2011-09-26 10 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(); 
} 

이 솔루션은 실제로 글고의 내용 변경이있을 때마다 다시 작성하기 때문에 당신은뿐만 아니라 다른 문제에 신경해야 할 수도 있습니다 . 예를 들어, 직접 삽입 한 문자는 처리하지 말아야합니다 (즉, 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; 
}