재정 관리에 도움이되는 앱을 작성하려고합니다. EditText
사용자가 금액을 지정할 수 있는 필드를 사용하고 있습니다.
나는 사람들이 돈에 적합하지 않은 숫자를 입력 할 수 있다는 점을 제외하고는 잘 작동 하는 inputType
것으로 설정했습니다 .numberDecimal
123.122
소수점 뒤의 문자 수를 2로 제한하는 방법이 있습니까?
답변
더 우아한 방법은 다음과 같이 정규식 (regex)을 사용하는 것입니다.
public class DecimalDigitsInputFilter implements InputFilter {
Pattern mPattern;
public DecimalDigitsInputFilter(int digitsBeforeZero,int digitsAfterZero) {
mPattern=Pattern.compile("[0-9]{0," + (digitsBeforeZero-1) + "}+((\\.[0-9]{0," + (digitsAfterZero-1) + "})?)||(\\.)?");
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
Matcher matcher=mPattern.matcher(dest);
if(!matcher.matches())
return "";
return null;
}
}
그것을 사용하려면 다음을 수행하십시오.
editText.setFilters(new InputFilter[] {new DecimalDigitsInputFilter(5,2)});
답변
정규식을 사용하지 않는 더 간단한 솔루션 :
import android.text.InputFilter;
import android.text.Spanned;
/**
* Input filter that limits the number of decimal digits that are allowed to be
* entered.
*/
public class DecimalDigitsInputFilter implements InputFilter {
private final int decimalDigits;
/**
* Constructor.
*
* @param decimalDigits maximum decimal digits
*/
public DecimalDigitsInputFilter(int decimalDigits) {
this.decimalDigits = decimalDigits;
}
@Override
public CharSequence filter(CharSequence source,
int start,
int end,
Spanned dest,
int dstart,
int dend) {
int dotPos = -1;
int len = dest.length();
for (int i = 0; i < len; i++) {
char c = dest.charAt(i);
if (c == '.' || c == ',') {
dotPos = i;
break;
}
}
if (dotPos >= 0) {
// protects against many dots
if (source.equals(".") || source.equals(","))
{
return "";
}
// if the text is entered before the dot
if (dend <= dotPos) {
return null;
}
if (len - dotPos > decimalDigits) {
return "";
}
}
return null;
}
}
쓰다:
editText.setFilters(new InputFilter[] {new DecimalDigitsInputFilter(2)});
답변
이 구현은 InputFilter
문제 를 해결합니다.
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.method.DigitsKeyListener;
public class MoneyValueFilter extends DigitsKeyListener {
public MoneyValueFilter() {
super(false, true);
}
private int digits = 2;
public void setDigits(int d) {
digits = d;
}
@Override
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
CharSequence out = super.filter(source, start, end, dest, dstart, dend);
// if changed, replace the source
if (out != null) {
source = out;
start = 0;
end = out.length();
}
int len = end - start;
// if deleting, source is empty
// and deleting can't break anything
if (len == 0) {
return source;
}
int dlen = dest.length();
// Find the position of the decimal .
for (int i = 0; i < dstart; i++) {
if (dest.charAt(i) == '.') {
// being here means, that a number has
// been inserted after the dot
// check if the amount of digits is right
return (dlen-(i+1) + len > digits) ?
"" :
new SpannableStringBuilder(source, start, end);
}
}
for (int i = start; i < end; ++i) {
if (source.charAt(i) == '.') {
// being here means, dot has been inserted
// check if the amount of digits is right
if ((dlen-dend) + (end-(i + 1)) > digits)
return "";
else
break; // return new SpannableStringBuilder(source, start, end);
}
}
// if the dot is after the inserted part,
// nothing can break
return new SpannableStringBuilder(source, start, end);
}
}
답변
다음은 소수점 앞 최대 4 자리와 그 이후 최대 1 자리 만 허용 하는 샘플 InputFilter 입니다.
값 글고 치기는 허용 : 555.2 , 555 , 0.2
텍스트 블록을 편집하는 값 : 55555.2 , 055.2 , 555.42
InputFilter filter = new InputFilter() {
final int maxDigitsBeforeDecimalPoint=4;
final int maxDigitsAfterDecimalPoint=1;
@Override
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
StringBuilder builder = new StringBuilder(dest);
builder.replace(dstart, dend, source
.subSequence(start, end).toString());
if (!builder.toString().matches(
"(([1-9]{1})([0-9]{0,"+(maxDigitsBeforeDecimalPoint-1)+"})?)?(\\.[0-9]{0,"+maxDigitsAfterDecimalPoint+"})?"
)) {
if(source.length()==0)
return dest.subSequence(dstart, dend);
return "";
}
return null;
}
};
mEdittext.setFilters(new InputFilter[] { filter });
답변
@Pinhassi 솔루션을 수정했습니다. 다음과 같은 경우를 처리합니다.
1. 커서를 어디로 든 이동할 수 있습니다.
2. 마이너스 기호 처리
3.digitsbefore = 2 및 numbersafter = 4이고 12.4545를 입력합니다. 그런 다음 “.”을 제거하려는 경우 허용되지 않습니다.
public class DecimalDigitsInputFilter implements InputFilter {
private int mDigitsBeforeZero;
private int mDigitsAfterZero;
private Pattern mPattern;
private static final int DIGITS_BEFORE_ZERO_DEFAULT = 100;
private static final int DIGITS_AFTER_ZERO_DEFAULT = 100;
public DecimalDigitsInputFilter(Integer digitsBeforeZero, Integer digitsAfterZero) {
this.mDigitsBeforeZero = (digitsBeforeZero != null ? digitsBeforeZero : DIGITS_BEFORE_ZERO_DEFAULT);
this.mDigitsAfterZero = (digitsAfterZero != null ? digitsAfterZero : DIGITS_AFTER_ZERO_DEFAULT);
mPattern = Pattern.compile("-?[0-9]{0," + (mDigitsBeforeZero) + "}+((\\.[0-9]{0," + (mDigitsAfterZero)
+ "})?)||(\\.)?");
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
String replacement = source.subSequence(start, end).toString();
String newVal = dest.subSequence(0, dstart).toString() + replacement
+ dest.subSequence(dend, dest.length()).toString();
Matcher matcher = mPattern.matcher(newVal);
if (matcher.matches())
return null;
if (TextUtils.isEmpty(source))
return dest.subSequence(dstart, dend);
else
return "";
}
}
답변
다른 솔루션이 마음에 들지 않아 직접 만들었습니다. 이 솔루션을 사용하면 포인트 앞에 MAX_BEFORE_POINT 자리 이상을 입력 할 수 없으며 소수점은 MAX_DECIMAL 이상일 수 없습니다.
숫자를 초과하여 입력 할 수 없으며 다른 효과는 없습니다! 추가로 “.”라고 쓰면 “0”을 입력합니다.
-
레이아웃의 EditText를 다음과 같이 설정합니다.
android : inputType = “numberDecimal”
-
onCreate에 리스너를 추가하십시오. 점 편집 전후의 자릿수를 수정하려면 PerfectDecimal (str, NUMBER_BEFORE_POINT, NUMBER_DECIMALS) 호출을 편집하십시오. 여기에서 3과 2로 설정합니다.
EditText targetEditText = (EditText)findViewById(R.id.targetEditTextLayoutId); targetEditText.addTextChangedListener(new TextWatcher() { public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {} public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {} public void afterTextChanged(Editable arg0) { String str = targetEditText.getText().toString(); if (str.isEmpty()) return; String str2 = PerfectDecimal(str, 3, 2); if (!str2.equals(str)) { targetEditText.setText(str2); int pos = targetEditText.getText().length(); targetEditText.setSelection(pos); } } });
-
이 기능 포함 :
public String PerfectDecimal(String str, int MAX_BEFORE_POINT, int MAX_DECIMAL){ if(str.charAt(0) == '.') str = "0"+str; int max = str.length(); String rFinal = ""; boolean after = false; int i = 0, up = 0, decimal = 0; char t; while(i < max){ t = str.charAt(i); if(t != '.' && after == false){ up++; if(up > MAX_BEFORE_POINT) return rFinal; }else if(t == '.'){ after = true; }else{ decimal++; if(decimal > MAX_DECIMAL) return rFinal; } rFinal = rFinal + t; i++; }return rFinal; }
그리고 끝났습니다!
답변
나는 TextWatcher
다음과 같은 방법으로 이것을 달성했습니다.
final EditText et = (EditText) findViewById(R.id.EditText1);
int count = -1;
et.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence arg0, int arg1, int arg2,int arg3) {
}
public void beforeTextChanged(CharSequence arg0, int arg1,int arg2, int arg3) {
}
public void afterTextChanged(Editable arg0) {
if (arg0.length() > 0) {
String str = et.getText().toString();
et.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DEL) {
count--;
InputFilter[] fArray = new InputFilter[1];
fArray[0] = new InputFilter.LengthFilter(100);
et.setFilters(fArray);
//change the edittext's maximum length to 100.
//If we didn't change this the edittext's maximum length will
//be number of digits we previously entered.
}
return false;
}
});
char t = str.charAt(arg0.length() - 1);
if (t == '.') {
count = 0;
}
if (count >= 0) {
if (count == 2) {
InputFilter[] fArray = new InputFilter[1];
fArray[0] = new InputFilter.LengthFilter(arg0.length());
et.setFilters(fArray);
//prevent the edittext from accessing digits
//by setting maximum length as total number of digits we typed till now.
}
count++;
}
}
}
});
이 솔루션은 사용자가 소수점 뒤에 두 자리 이상을 입력하는 것을 허용하지 않습니다. 또한 소수점 앞에 임의의 자릿수를 입력 할 수 있습니다. 여러 EditText에 대한 필터를 설정하려면 http://v4all123.blogspot.com/2013/05/set-limit-for-fraction-in-decimal.html 블로그를 참조하십시오 . 이것이 도움이되기를 바랍니다. 감사합니다.