2013-08-09 2 views
1

숫자/십진수 편집 텍스트 필드에 십진수 값을 1 개 이상 입력하지 못하도록 사용자를 제한해야합니다. 즉, 숫자 입력을 최대 6 자리로 제한해야합니다. 예. 999999.9사용자가 텍스트 편집에서 10 진수 값 1을 입력하도록 제한

사용자가 숫자 만 입력하면 사용자를 최대 6 자리로 제한 할 수 있지만 "."허용해야합니다. 십진수 (사용자가 입력 한 경우).

잘 모르겠습니다. 어떻게해야합니까? 모든 도움과 참조는 큰 도움이 될 것입니다.

+0

사용 TextWatcher. http://learnandroideasily.blogspot.in/2013/06/using-textwatcher-in-android.html –

+0

나는 TextWatcher를 사용해야한다는 것을 알았지 만 문제는 언급 된 경우에 동적으로 사용자를 제한하는 방법에 관한 것입니다. 위. 즉, 숫자가 6 개의 문자 및 십진수 1 개의 문자로 제한되는 경우. – sku

답변

4

이와 비슷한 구현의 형식을 텍스트 변경에 DecimalFormat에 대한 알림을받을 수 있습니다? 나는 그것이 많이 최적화 될 수 있다고 확신한다!

EditText et; 
..... 
// force number input type on edittext 
et.setRawInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL); 
et.addTextChangedListener(new CustomTextWatcher(et)); 

여기서

class CustomTextWatcher implements TextWatcher { 
    private NumberFormat nf = NumberFormat.getNumberInstance(); 
    private EditText et; 
    private String tmp = ""; 
    private int moveCaretTo; 
    private static final int INTEGER_CONSTRAINT = 6; 
    private static final int FRACTION_CONSTRAINT = 1; 
    private static final int MAX_LENGTH = INTEGER_CONSTRAINT + FRACTION_CONSTRAINT + 1; 

    public CustomTextWatcher(EditText et) { 
     this.et = et; 
     nf.setMaximumIntegerDigits(INTEGER_CONSTRAINT); 
     nf.setMaximumFractionDigits(FRACTION_CONSTRAINT); 
     nf.setGroupingUsed(false); 
    } 

    public int countOccurrences(String str, char c) { 
     int count = 0; 
     for (int i = 0; i < str.length(); i++) { 
      if (str.charAt(i) == c) { 
       count++; 
      } 
     } 
     return count; 
    } 

    @Override 
    public void afterTextChanged(Editable s) { 
     et.removeTextChangedListener(this); // remove to prevent stackoverflow 
     String ss = s.toString(); 
     int len = ss.length(); 
     int dots = countOccurrences(ss, '.'); 
     boolean shouldParse = dots <= 1 && (dots == 0 ? len != (INTEGER_CONSTRAINT + 1) : len < (MAX_LENGTH + 1)); 
     if (shouldParse) { 
      if (len > 1 && ss.lastIndexOf(".") != len - 1) { 
       try { 
        Double d = Double.parseDouble(ss); 
        if (d != null) { 
         et.setText(nf.format(d)); 
        } 
       } catch (NumberFormatException e) { 
       } 
      } 
     } else { 
      et.setText(tmp); 
     } 
     et.addTextChangedListener(this); // reset listener 

     //tried to fix caret positioning after key type: 
     if (et.getText().toString().length() > 0) { 
      if (dots == 0 && len >= INTEGER_CONSTRAINT && moveCaretTo > INTEGER_CONSTRAINT) { 
       moveCaretTo = INTEGER_CONSTRAINT; 
      } else if (dots > 0 && len >= (MAX_LENGTH) && moveCaretTo > (MAX_LENGTH)) { 
       moveCaretTo = MAX_LENGTH; 
      } 
      try { 
       et.setSelection(et.getText().toString().length()); 
       // et.setSelection(moveCaretTo); <- almost had it :)) 
      } catch (Exception e) { 
      } 
     } 
    } 

    @Override 
    public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
     moveCaretTo = et.getSelectionEnd(); 
     tmp = s.toString(); 
    } 

    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 
     int length = et.getText().toString().length(); 
     if (length > 0) { 
      moveCaretTo = start + count - before; 
     } 
    } 
} 

100 %하지만 당신은 기본으로 사용하고 그 위에 구축 할 수 있습니다)

편집 :는 캐럿 위치 후 설정 연마에 노력 텍스트가 변경되었지만 예상보다 어려웠고 각 문자 입력 후 끝 부분에 캐럿을 설정했습니다. 나는 당신이 그것을 향상시킬 수있는 탈자를 위해 시작한 코드를 남겼다.

+0

코드가 작동합니다. 단, Number가 6에 도달하면 그 이후에 10 진수 값을 더할 수 없습니다. – sku

+0

그래, 나는 똑같은 코드를 가지고있다. 명확히하기 위해 경계 구분은 완벽하게 작동합니다. 그러나 숫자가 6 자 길이가되면 '.' 구분 기호는 편집 텍스트에 표시되지 않습니다. 그 일이 보입니까? 그건 그렇고,이 일에 많은 도움을 주신 것에 감사드립니다. – sku

+1

@ Marci, 나쁘다. 나는 layout.xml에서 Max 길이를 6으로 설정했다. 이제는 제거 했으므로 원하는대로 작동합니다. 그러나 대체 텍스트를 가져 오는 것과 같은 사소한 문제는 거의 없으며 디버깅을 시도 할 것입니다. 당신의 모든 의견은 큰 도움이 될 것입니다. 이 시점에서, 나는 당신이 나를 많이 도와 준 것 같아. 대답을 수락하고 그 점에 보상 할 것입니다. 고마워요. – sku

2

내가 하나가 아래의 코드를 사용하여 편집 위의 대답

의 작은 실수 있습니다.

import java.math.RoundingMode; 
import java.text.NumberFormat; 

import android.text.Editable; 
import android.text.TextWatcher; 
import android.widget.EditText; 

public class DecimalTextWatcher implements TextWatcher { 
    private NumberFormat numberFormat = NumberFormat.getNumberInstance(); 
    private EditText editText; 
    private String temp = ""; 
    private int moveCaretTo; 
    private int integerConstraint; 
    private int fractionConstraint; 
    private int maxLength; 

    /** 
    * Add a text watcher to Edit text for decimal formats 
    * 
    * @param editText 
    *   EditText to add DecimalTextWatcher 
    * @param before 
    *   digits before decimal point 
    * @param after 
    *   digits after decimal point 
    */ 
    public DecimalTextWatcher(EditText editText, int before, int after) { 
     this.editText = editText; 
     this.integerConstraint = before; 
     this.fractionConstraint = after; 
     this.maxLength = before + after + 1; 
     numberFormat.setMaximumIntegerDigits(integerConstraint); 
     numberFormat.setMaximumFractionDigits(fractionConstraint); 
     numberFormat.setRoundingMode(RoundingMode.DOWN); 
     numberFormat.setGroupingUsed(false); 
    } 

    private int countOccurrences(String str, char c) { 
     int count = 0; 
     for (int i = 0; i < str.length(); i++) { 
      if (str.charAt(i) == c) { 
       count++; 
      } 
     } 
     return count; 
    } 

    @Override 
    public void afterTextChanged(Editable s) { 
     // remove to prevent StackOverFlowException 
     editText.removeTextChangedListener(this); 
     String ss = s.toString(); 
     int len = ss.length(); 
     int dots = countOccurrences(ss, '.'); 
     boolean shouldParse = dots <= 1 && (dots == 0 ? len != (integerConstraint + 1) : len < (maxLength + 1)); 
     boolean x = false; 
     if (dots == 1) { 
      int indexOf = ss.indexOf('.'); 
      try { 
       if (ss.charAt(indexOf + 1) == '0') { 
        shouldParse = false; 
        x = true; 
        if (ss.substring(indexOf).length() > 2) { 
         shouldParse = true; 
         x = false; 
        } 
       } 
      } catch (Exception ex) { 
      } 
     } 
     if (shouldParse) { 
      if (len > 1 && ss.lastIndexOf(".") != len - 1) { 
       try { 
        Double d = Double.parseDouble(ss); 
        if (d != null) { 
         editText.setText(numberFormat.format(d)); 
        } 
       } catch (NumberFormatException e) { 
       } 
      } 
     } else { 
      if (x) { 
       editText.setText(ss); 
      } else { 
       editText.setText(temp); 
      } 
     } 
     editText.addTextChangedListener(this); // reset listener 

     // tried to fix caret positioning after key type: 
     if (editText.getText().toString().length() > 0) { 
      if (dots == 0 && len >= integerConstraint && moveCaretTo > integerConstraint) { 
       moveCaretTo = integerConstraint; 
      } else if (dots > 0 && len >= (maxLength) && moveCaretTo > (maxLength)) { 
       moveCaretTo = maxLength; 
      } 
      try { 
       editText.setSelection(editText.getText().toString().length()); 
       // et.setSelection(moveCaretTo); <- almost had it :)) 
      } catch (Exception e) { 
      } 
     } 
    } 

    @Override 
    public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
     moveCaretTo = editText.getSelectionEnd(); 
     temp = s.toString(); 
    } 

    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 
     int length = editText.getText().toString().length(); 
     if (length > 0) { 
      moveCaretTo = start + count - before; 
     } 
    } 
} 

다음과 같이 사용

.. 당신 글고 치기에

itemCostEditText.addTextChangedListener(new DecimalTextWatcher(itemCostEditText, 6, 2)); 
+0

위대한 작품. 왜 득표를하지 않았습니까? –

관련 문제