Android에서 소수 자릿수 제한
재정 관리에 도움이되는 앱을 강화합니다. EditText
가 금액을 user-지정할 수 있는 필드를 사용하고 있습니다.
나는 사람들이 돈을 위해 완벽하지 않은 숫자를 입력 입력 할 수 있다는 것을 제외하고는 잘 작동 하는 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, numericafter = 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 "";
}
}
나는 TextWatcher
다음과 같은 방법으로 달성했다.
final EditText et = (EditText) findViewById(R.id.EditText1);
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 을 참조하십시오 . 이것이 도움이되기를 바랍니다. 감사합니다.
나는 다른 솔루션을 좋아하지 않고 내 자신을 만들었습니다. 이 솔루션을 사용하면 포인트 앞에 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; }
그리고 끝났어!
내 솔루션은 간단하고 완벽하게 작동합니다!
public class DecimalInputTextWatcher implements TextWatcher {
private String mPreviousValue;
private int mCursorPosition;
private boolean mRestoringPreviousValueFlag;
private int mDigitsAfterZero;
private EditText mEditText;
public DecimalInputTextWatcher(EditText editText, int digitsAfterZero) {
mDigitsAfterZero = digitsAfterZero;
mEditText = editText;
mPreviousValue = "";
mRestoringPreviousValueFlag = false;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (!mRestoringPreviousValueFlag) {
mPreviousValue = s.toString();
mCursorPosition = mEditText.getSelectionStart();
}
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (!mRestoringPreviousValueFlag) {
if (!isValid(s.toString())) {
mRestoringPreviousValueFlag = true;
restorePreviousValue();
}
} else {
mRestoringPreviousValueFlag = false;
}
}
private void restorePreviousValue() {
mEditText.setText(mPreviousValue);
mEditText.setSelection(mCursorPosition);
}
private boolean isValid(String s) {
Pattern patternWithDot = Pattern.compile("[0-9]*((\\.[0-9]{0," + mDigitsAfterZero + "})?)||(\\.)?");
Pattern patternWithComma = Pattern.compile("[0-9]*((,[0-9]{0," + mDigitsAfterZero + "})?)||(,)?");
Matcher matcherDot = patternWithDot.matcher(s);
Matcher matcherComa = patternWithComma.matcher(s);
return matcherDot.matches() || matcherComa.matches();
}
}
용법 :
myTextEdit.addTextChangedListener(new DecimalInputTextWatcher(myTextEdit, 2));
요구 사항은 소수점 이하 2 자리입니다. 소수점 앞의 자릿수는 제한 이 없어야합니다 . 따라서 해결책은
public class DecimalDigitsInputFilter implements InputFilter {
Pattern mPattern;
public DecimalDigitsInputFilter() {
mPattern = Pattern.compile("[0-9]*+((\\.[0-9]?)?)||(\\.)?");
}
@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;
}
}
그리고 그것을 다음과 같이 사용하십시오.
mEditText.setFilters(new InputFilter[]{new DecimalDigitsInputFilter()});
영감을 주신 @Pinhassi에게 감사드립니다.
내가 입력 한 InputFilter를 사용하면 소수점 이하 자릿수를 구성 할 수 있습니다. 또한 선행 0을 허용하지 않습니다.
public class DecimalDigitsInputFilter implements InputFilter
{
Pattern pattern;
public DecimalDigitsInputFilter(int digitsBeforeDecimal, int digitsAfterDecimal)
{
pattern = Pattern.compile("(([1-9]{1}[0-9]{0," + (digitsBeforeDecimal - 1) + "})?||[0]{1})((\\.[0-9]{0," + digitsAfterDecimal + "})?)||(\\.)?");
}
@Override public CharSequence filter(CharSequence source, int sourceStart, int sourceEnd, Spanned destination, int destinationStart, int destinationEnd)
{
// Remove the string out of destination that is to be replaced.
String newString = destination.toString().substring(0, destinationStart) + destination.toString().substring(destinationEnd, destination.toString().length());
// Add the new string in.
newString = newString.substring(0, destinationStart) + source.toString() + newString.substring(destinationStart, newString.length());
// Now check if the new string is valid.
Matcher matcher = pattern.matcher(newString);
if(matcher.matches())
{
// Returning null indicates that the input is valid.
return null;
}
// Returning the empty string indicates the input is invalid.
return "";
}
}
// To use this InputFilter, attach it to your EditText like so:
final EditText editText = (EditText) findViewById(R.id.editText);
EditText.setFilters(new InputFilter[]{new DecimalDigitsInputFilter(4, 4)});
사용해보십시오 NumberFormat.getCurrencyInstance ()를 사용하면 텍스트 뷰에 넣어 전에 문자열을 포맷 할 수 있습니다.
다음과 같은 것 :
NumberFormat currency = NumberFormat.getCurrencyInstance();
myTextView.setText(currency.format(dollars));
편집 -문서에서 수있는 통화에 대한 inputType이 없습니다. 일본 엔과 같이 소수점 이하 자릿수에 대해 규칙을 따르지 않는 통화가 있기 때문에 이것이 가능하다고 생각합니다.
LeffelMania가 참조했듯이 위의 코드 TextWatcher
를 사용하여 사용자 입력을 수 있습니다 EditText
.
@Pinhassi 솔루션을 약간 개선했습니다.
잘 작동합니다. 하나의 유효성을 검사합니다.
public class DecimalDigitsInputFilter implements InputFilter {
Pattern mPattern;
public DecimalDigitsInputFilter() {
mPattern = Pattern.compile("([1-9]{1}[0-9]{0,2}([0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)");
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
String formatedSource = source.subSequence(start, end).toString();
String destPrefix = dest.subSequence(0, dstart).toString();
String destSuffix = dest.subSequence(dend, dest.length()).toString();
String result = destPrefix + formatedSource + destSuffix;
result = result.replace(",", ".");
Matcher matcher = mPattern.matcher(result);
if (matcher.matches()) {
return null;
}
return "";
}
}
위의 솔루션을 수정하고 다음 중 하나를 만들었습니다. 위치 전후 자릿수를 수 있습니다.
public class DecimalDigitsInputFilter implements InputFilter {
private final Pattern mPattern;
public DecimalDigitsInputFilter(int digitsBeforeZero, int digitsAfterZero) {
mPattern = Pattern.compile(String.format("[0-9]{0,%d}(\\.[0-9]{0,%d})?", digitsBeforeZero, digitsAfterZero));
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
Matcher matcher = mPattern.matcher(createResultString(source, start, end, dest, dstart, dend));
if (!matcher.matches())
return "";
return null;
}
private String createResultString(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
String sourceString = source.toString();
String destString = dest.toString();
return destString.substring(0, dstart) + sourceString.substring(start, end) + destString.substring(dend);
}
}
DecimalFormat form = new DecimalFormat("#.##", new DecimalFormatSymbols(Locale.US));
EditText et;
et.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
double a = Double.parseDouble(et.getText().toString());
et.setText(form.format(a));
}
return false;
}
});
편집 단계를 종료하면 필드가 올바른 형식으로 형식화됩니다. 그 순간에는 소수점 이하 2 자만 있습니다. 나는 매우 쉬운 방법이라고 생각합니다.
여기에있는 모든 답변은 복잡해서 간단하게 만들려고했습니다. 내 코드를 스스로 결정하십시오.
int temp = 0;
int check = 0;
editText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(editText.getText().toString().length()<temp)
{
if(!editText.getText().toString().contains("."))
editText.setFilters(new InputFilter[] { new InputFilter.LengthFilter(editText.getText().toString().length()-1) });
else
editText.setFilters(new InputFilter[] { new InputFilter.LengthFilter(editText.getText().toString().length()+1) });
}
if(!editText.getText().toString().contains("."))
{
editText.setFilters(new InputFilter[] { new InputFilter.LengthFilter(editText.getText().toString().length()+1) });
check=0;
}
else if(check==0)
{
check=1;
editText.setFilters(new InputFilter[] { new InputFilter.LengthFilter(editText.getText().toString().length()+2) });
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
temp = editText.getText().toString().length();
}
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
나는 Pinhassi의 대답을 좋아했지만 사용자가 더 많은 숫자를 입력하면 더 이상 숫자에 텍스트를 입력 할 수 있습니다. 문제는 솔루션이 입력 된 현재 텍스트가 아니라 이전에 입력 한 텍스트 만 테스트한다는 것입니다. 여기 유효성 검사를 위해 새 문자를 원본 텍스트에 삽입하는 솔루션이 있습니다.
package com.test.test;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.text.InputFilter;
import android.text.Spanned;
import android.util.Log;
public class InputFilterCurrency implements InputFilter {
Pattern moPattern;
public InputFilterCurrency(int aiMinorUnits) {
// http://www.regexplanet.com/advanced/java/index.html
moPattern=Pattern.compile("[0-9]*+((\\.[0-9]{0,"+ aiMinorUnits + "})?)||(\\.)?");
} // InputFilterCurrency
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
String lsStart = "";
String lsInsert = "";
String lsEnd = "";
String lsText = "";
Log.d("debug", moPattern.toString());
Log.d("debug", "source: " + source + ", start: " + start + ", end:" + end + ", dest: " + dest + ", dstart: " + dstart + ", dend: " + dend );
lsText = dest.toString();
// If the length is greater then 0, then insert the new character
// into the original text for validation
if (lsText.length() > 0) {
lsStart = lsText.substring(0, dstart);
Log.d("debug", "lsStart : " + lsStart);
// Check to see if they have deleted a character
if (source != "") {
lsInsert = source.toString();
Log.d("debug", "lsInsert: " + lsInsert);
} // if
lsEnd = lsText.substring(dend);
Log.d("debug", "lsEnd : " + lsEnd);
lsText = lsStart + lsInsert + lsEnd;
Log.d("debug", "lsText : " + lsText);
} // if
Matcher loMatcher = moPattern.matcher(lsText);
Log.d("debug", "loMatcher.matches(): " + loMatcher.matches() + ", lsText: " + lsText);
if(!loMatcher.matches()) {
return "";
}
return null;
} // CharSequence
} // InputFilterCurrency
그리고 editText 필터를 설정하는 호출
editText.setFilters(new InputFilter[] {new InputFilterCurrency(2)});
Ouput with two decimal places
05-22 15:25:33.434: D/debug(30524): [0-9]*+((\.[0-9]{0,2})?)||(\.)?
05-22 15:25:33.434: D/debug(30524): source: 5, start: 0, end:1, dest: 123.4, dstart: 5, dend: 5
05-22 15:25:33.434: D/debug(30524): lsStart : 123.4
05-22 15:25:33.434: D/debug(30524): lsInsert: 5
05-22 15:25:33.434: D/debug(30524): lsEnd :
05-22 15:25:33.434: D/debug(30524): lsText : 123.45
05-22 15:25:33.434: D/debug(30524): loMatcher.matches(): true, lsText: 123.45
Ouput inserting a 5 in the middle
05-22 15:26:17.624: D/debug(30524): [0-9]*+((\.[0-9]{0,2})?)||(\.)?
05-22 15:26:17.624: D/debug(30524): source: 5, start: 0, end:1, dest: 123.45, dstart: 2, dend: 2
05-22 15:26:17.624: D/debug(30524): lsStart : 12
05-22 15:26:17.624: D/debug(30524): lsInsert: 5
05-22 15:26:17.624: D/debug(30524): lsEnd : 3.45
05-22 15:26:17.624: D/debug(30524): lsText : 1253.45
05-22 15:26:17.624: D/debug(30524): loMatcher.matches(): true, lsText: 1253.45
Pinhassi의 정규 용도를 사용하는 솔루션을 개선하여 처리합니다. 입력이 올바른지 확인하기 전에 먼저 Android 문서에 설명 된대로 최종을 구성하십시오.
public class DecimalDigitsInputFilter implements InputFilter {
private Pattern mPattern;
private static final Pattern mFormatPattern = Pattern.compile("\\d+\\.\\d+");
public DecimalDigitsInputFilter(int digitsBeforeDecimal, int digitsAfterDecimal) {
mPattern = Pattern.compile(
"^\\d{0," + digitsBeforeDecimal + "}([\\.,](\\d{0," + digitsAfterDecimal +
"})?)?$");
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest,
int dstart, int dend) {
String newString =
dest.toString().substring(0, dstart) + source.toString().substring(start, end)
+ dest.toString().substring(dend, dest.toString().length());
Matcher matcher = mPattern.matcher(newString);
if (!matcher.matches()) {
return "";
}
return null;
}
}
용법 :
editText.setFilters(new InputFilter[] {new DecimalDigitsInputFilter(5,2)});
간단한 도우미 클래스는 사용자가 소수점 이하 두 자리 이상을 입력하지 못하도록합니다.
public class CostFormatter implements TextWatcher {
private final EditText costEditText;
public CostFormatter(EditText costEditText) {
this.costEditText = costEditText;
}
@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 synchronized void afterTextChanged(final Editable text) {
String cost = text.toString().trim();
if(!cost.endsWith(".") && cost.contains(".")){
String numberBeforeDecimal = cost.split("\\.")[0];
String numberAfterDecimal = cost.split("\\.")[1];
if(numberAfterDecimal.length() > 2){
numberAfterDecimal = numberAfterDecimal.substring(0, 2);
}
cost = numberBeforeDecimal + "." + numberAfterDecimal;
}
costEditText.removeTextChangedListener(this);
costEditText.setText(cost);
costEditText.setSelection(costEditText.getText().toString().trim().length());
costEditText.addTextChangedListener(this);
}
}
첫 번째 위치에 포인트를 넣을 수 있기 때문에 답변 №6 (Favas Kv)을 (를) 변경했습니다.
final InputFilter [] filter = { new InputFilter() {
@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,4})?(\\.)?)?([0-9]{0,2})?"
)) {
if(source.length()==0)
return dest.subSequence(dstart, dend);
return "";
}
return null;
}
}};
다른 사람들이 말했듯이, 나는이 클래스를 프로젝트에 추가하고 필터를 EditText
원하는 대로 설정했습니다 .
필터는 @Pixel의 답변에서 복사됩니다. 나는 단지 그것을 모두 모으고 있습니다.
public class DecimalDigitsInputFilter implements InputFilter {
Pattern mPattern;
public DecimalDigitsInputFilter() {
mPattern = Pattern.compile("([1-9]{1}[0-9]{0,2}([0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)");
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
String formatedSource = source.subSequence(start, end).toString();
String destPrefix = dest.subSequence(0, dstart).toString();
String destSuffix = dest.subSequence(dend, dest.length()).toString();
String result = destPrefix + formatedSource + destSuffix;
result = result.replace(",", ".");
Matcher matcher = mPattern.matcher(result);
if (matcher.matches()) {
return null;
}
return "";
}
}
이제 필터를 EditText
이와 같이 설정하십시오 .
mEditText.setFilters(new InputFilter[]{new DecimalDigitsInputFilter()});
한 가지 중요한 ... 여기서 점은 해결할 수있는 문제를한다는 점에서 소수점 이후 두 개 이상의 숫자를 보여주는 허용하지 않는 내 문제를 않는을 구석으로입니다 EditText
하지만 난 때 문제는 getText()
것과 EditText
, 그것이 내가 입력 한 모든 입력을 반환 합니다 .
예를 들어에 필터를 적용한 후 EditText
입력 1.5699856987을 설정했습니다. 화면에 1.56이 표시됩니다.
그런 다음이 입력을 다른 계산에 사용하고 싶기 때문에 해당 입력 필드 ( EditText
) 에서 텍스트를 가져 왔습니다 . 내가 전화했을 때 mEditText.getText().toString()
1.5699856987을 반환했는데 내 경우에는 받아 들일 수 없습니다.
그래서에서 값을 얻은 후 값을 다시 구문 분석해야했습니다 EditText
.
BigDecimal amount = new BigDecimal(Double.parseDouble(mEditText.getText().toString().trim()))
.setScale(2, RoundingMode.HALF_UP);
setScale
에서 전체 텍스트를 장비 후 여기 트릭을 수행합니다 EditText
.
나는 또한이 문제를 집었습니다. 많은 EditText에서 코드를 함께 할 수 있기 때문에 원했습니다. 이것은 내 솔루션입니다.
사용법 :
CurrencyFormat watcher = new CurrencyFormat();
priceEditText.addTextChangedListener(watcher);
수업 :
public static class CurrencyFormat implements TextWatcher {
public void onTextChanged(CharSequence arg0, int start, int arg2,int arg3) {}
public void beforeTextChanged(CharSequence arg0, int start,int arg2, int arg3) {}
public void afterTextChanged(Editable arg0) {
int length = arg0.length();
if(length>0){
if(nrOfDecimal(arg0.toString())>2)
arg0.delete(length-1, length);
}
}
private int nrOfDecimal(String nr){
int len = nr.length();
int pos = len;
for(int i=0 ; i<len; i++){
if(nr.charAt(i)=='.'){
pos=i+1;
break;
}
}
return len-pos;
}
}
당신을 위해 @Meh ..
txtlist.setFilters(new InputFilter[] { new DigitsKeyListener( Boolean.FALSE,Boolean.TRUE) {
int beforeDecimal = 7;
int afterDecimal = 2;
@Override
public CharSequence filter(CharSequence source, int start, int end,Spanned dest, int dstart, int dend) {
String etText = txtlist.getText().toString();
String temp = txtlist.getText() + source.toString();
if (temp.equals(".")) {
return "0.";
} else if (temp.toString().indexOf(".") == -1) {
// no decimal point placed yet
if (temp.length() > beforeDecimal) {
return "";
}
} else {
int dotPosition ;
int cursorPositon = txtlistprice.getSelectionStart();
if (etText.indexOf(".") == -1) {
dotPosition = temp.indexOf(".");
}else{
dotPosition = etText.indexOf(".");
}
if(cursorPositon <= dotPosition){
String beforeDot = etText.substring(0, dotPosition);
if(beforeDot.length()<beforeDecimal){
return source;
}else{
if(source.toString().equalsIgnoreCase(".")){
return source;
}else{
return "";
}
}
}else{
temp = temp.substring(temp.indexOf(".") + 1);
if (temp.length() > afterDecimal) {
return "";
}
}
}
return super.filter(source, start, end, dest, dstart, dend);
}
} });
매우 늦게 응답 : 우리는 다음과 같이 할 수 있습니다.
etv.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) {
if (s.toString().length() > 3 && s.toString().contains(".")) {
if (s.toString().length() - s.toString().indexOf(".") > 3) {
etv.setText(s.toString().substring(0, s.length() - 1));
etv.setSelection(edtSendMoney.getText().length());
}
}
}
@Override
public void afterTextChanged(Editable arg0) {
}
}
내 해결은 다음과 달라집니다.
yourEditText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
NumberFormat formatter = new DecimalFormat("#.##");
double doubleVal = Double.parseDouble(s.toString());
yourEditText.setText(formatter.format(doubleVal));
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,int after) {}
@Override
public void afterTextChanged(Editable s) {}
});
소수점 이하 두 자리 이상의 숫자를 입력하면 자동으로 수정됩니다.
도움이 되셨기를 바랍니다.
이것은 나를 위해 잘 작동합니다. 점점 바뀌고 다시 검색된 후에도 값을 입력 할 수 있습니다. 예를 들면 : 123.00
, 12.12
, 0.01
, 등
1. 파일 에서 액세스 Integer.parseInt(getString(R.string.valuelength))
하는 입력 길이를 지정 합니다. 값을 조용히 변경하는 것은 조용합니다. 2. 소수점 이하 자릿수 최대 한도입니다.digits.Values
string.xml
Integer.parseInt(getString(R.string.valuedecimal))
private InputFilter[] valDecimalPlaces;
private ArrayList<EditText> edittextArray;
valDecimalPlaces = new InputFilter[] { new DecimalDigitsInputFilterNew(
Integer.parseInt(getString(R.string.valuelength)),
Integer.parseInt(getString(R.string.valuedecimal)))
};
EditText
작업을 수행 할 수 있는 값의 배열입니다 .
for (EditText etDecimalPlace : edittextArray) {
etDecimalPlace.setFilters(valDecimalPlaces);
방금 여러 개의 편집 텍스트 다음 DecimalDigitsInputFilterNew.class
파일 을 포함하는 값의 배열을 사용했습니다 .
import android.text.InputFilter;
import android.text.Spanned;
public class DecimalDigitsInputFilterNew implements InputFilter {
private final int decimalDigits;
private final int before;
public DecimalDigitsInputFilterNew(int before ,int decimalDigits) {
this.decimalDigits = decimalDigits;
this.before = before;
}
@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("(([0-9]{1})([0-9]{0,"+(before-1)+"})?)?(\\.[0-9]{0,"+decimalDigits+"})?")) {
if(source.length()==0)
return dest.subSequence(dstart, dend);
return "";
}
return null;
}
}
이 핀 하시의 대답을 바탕으로합니다. 소수 한계에 도달 할 수있는 가능성이 있습니다. 이 문제를 해결하기 전에 해결 비용 패턴 일치를 수행하기 전에 수행해야합니다.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.text.InputFilter;
import android.text.Spanned;
public class DecimalLimiter implements InputFilter
{
Pattern mPattern;
public DecimalLimiter(int digitsBeforeZero,int digitsAfterZero)
{
mPattern=Pattern.compile("[0-9]{0," + (digitsBeforeZero) + "}+((\\.[0-9]{0," + (digitsAfterZero) + "})?)||(\\.)?");
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)
{
StringBuilder sb = new StringBuilder(dest);
sb.insert(dstart, source, start, end);
Matcher matcher = mPattern.matcher(sb.toString());
if(!matcher.matches())
return "";
return null;
}
}
et = (EditText) vw.findViewById(R.id.tx_edittext);
et.setFilters(new InputFilter[] {
new DigitsKeyListener(Boolean.FALSE, Boolean.TRUE) {
int beforeDecimal = 5, afterDecimal = 2;
@Override
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
String temp = et.getText() + source.toString();
if (temp.equals(".")) {
return "0.";
}
else if (temp.toString().indexOf(".") == -1) {
// no decimal point placed yet
if (temp.length() > beforeDecimal) {
return "";
}
} else {
temp = temp.substring(temp.indexOf(".") + 1);
if (temp.length() > afterDecimal) {
return "";
}
}
return super.filter(source, start, end, dest, dstart, dend);
}
}
});
소수점 이하 n 자릿수 TextWatcher
만 허용 하는 것 입니다 .
TextWatcher
private static boolean flag;
public static TextWatcher getTextWatcherAllowAfterDeci(final int allowAfterDecimal){
TextWatcher watcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
String str = s.toString();
int index = str.indexOf ( "." );
if(index>=0){
if((index+1)<str.length()){
String numberD = str.substring(index+1);
if (numberD.length()!=allowAfterDecimal) {
flag=true;
}else{
flag=false;
}
}else{
flag = false;
}
}else{
flag=false;
}
if(flag)
s.delete(s.length() - 1,
s.length());
}
};
return watcher;
}
사용하는 방법
yourEditText.addTextChangedListener(getTextWatcherAllowAfterDeci(1));
달성하는 가장 간단한 방법은 다음과 가능합니다.
et.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
String text = arg0.toString();
if (text.contains(".") && text.substring(text.indexOf(".") + 1).length() > 2) {
et.setText(text.substring(0, text.length() - 1));
et.setSelection(et.getText().length());
}
}
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
public void afterTextChanged(Editable arg0) {
}
});
이 코드는 잘 작동합니다.
public class DecimalDigitsInputFilter implements InputFilter {
private final int digitsBeforeZero;
private final int digitsAfterZero;
private Pattern mPattern;
public DecimalDigitsInputFilter(int digitsBeforeZero, int digitsAfterZero) {
this.digitsBeforeZero = digitsBeforeZero;
this.digitsAfterZero = digitsAfterZero;
applyPattern(digitsBeforeZero, digitsAfterZero);
}
private void applyPattern(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) {
if (dest.toString().contains(".") || source.toString().contains("."))
applyPattern(digitsBeforeZero + 2, digitsAfterZero);
else
applyPattern(digitsBeforeZero, digitsAfterZero);
Matcher matcher = mPattern.matcher(dest);
if (!matcher.matches())
return "";
return null;
}
}
필터 적용 :
edittext.setFilters(new InputFilter[] {new DecimalDigitsInputFilter(5,2)});
참고 URL : https://stackoverflow.com/questions/5357455/limit-decimal-places-in-android-edittext
'IT' 카테고리의 다른 글
C에서 % n 형식 지정 튼 사용하는 것은 무엇입니까? (0) | 2020.07.21 |
---|---|
Mysql“show processlist”의 모든 프로세스를 어떻게 종료합니까? (0) | 2020.07.21 |
패턴에 대한 파일 텍스트를 검색하고 주어진 값으로 바꾸는 방법 (0) | 2020.07.21 |
도커 작성 영구 데이터 MySQL (0) | 2020.07.20 |
현재 글자가 메인 보드인지 확인 (0) | 2020.07.20 |