有没有办法在Android中定义EditText的最小值和最大值?
我想为EditText
定义最小值和最大值。
例如:如果有人试图在其中input月份值,则该值必须在1-12之间。
我可以通过使用TextWatcher
来做到这一点,但我想知道是否有任何其他方式在布局文件或其他地方做到这一点。
编辑:我不想限制字符数。 我想限制价值。 例如,如果我在input12时限制月份EditText
w个字符,它将接受它,但如果我input22,则在我input时不能接受它。
首先让这个类:
package com.test; import android.text.InputFilter; import android.text.Spanned; public class InputFilterMinMax implements InputFilter { private int min, max; public InputFilterMinMax(int min, int max) { this.min = min; this.max = max; } public InputFilterMinMax(String min, String max) { this.min = Integer.parseInt(min); this.max = Integer.parseInt(max); } @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { try { int input = Integer.parseInt(dest.toString() + source.toString()); if (isInRange(min, max, input)) return null; } catch (NumberFormatException nfe) { } return ""; } private boolean isInRange(int a, int b, int c) { return b > a ? c >= a && c <= b : c >= b && c <= a; } }
然后从你的Activity中使用这个:
EditText et = (EditText) findViewById(R.id.myEditText); et.setFilters(new InputFilter[]{ new InputFilterMinMax("1", "12")});
这将允许用户input1到12的值 。
编辑:
用android:inputType="number"
设置你的edittext。
谢谢。
Pratik的代码有一个小错误。 例如,如果一个值为10,并且在开始时加1以使得110,那么filter函数会将新值视为101。
请参阅下面的解决方法:
@Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { try { // Remove the string out of destination that is to be replaced String newVal = dest.toString().substring(0, dstart) + dest.toString().substring(dend, dest.toString().length()); // Add the new string in newVal = newVal.substring(0, dstart) + source.toString() + newVal.substring(dstart, newVal.length()); int input = Integer.parseInt(newVal); if (isInRange(min, max, input)) return null; } catch (NumberFormatException nfe) { } return ""; }
我扩展@Pratik Sharmas代码来使用BigDecimal对象,而不是整数,以便它可以接受更大的数字,并在EditText中说明任何不是数字的格式(如货币格式,即空格,逗号和句点)
编辑:请注意,这个实现有2个作为BigDecimal(请参阅MIN_SIG_FIG常量)上设置的最小有效数字,因为我用它的货币,所以总是有小数点前2个数字。 根据需要修改MIN_SIG_FIG常量以实现自己的实现。
public class InputFilterMinMax implements InputFilter { private static final int MIN_SIG_FIG = 2; private BigDecimal min, max; public InputFilterMinMax(BigDecimal min, BigDecimal max) { this.min = min; this.max = max; } public InputFilterMinMax(String min, String max) { this.min = new BigDecimal(min); this.max = new BigDecimal(max); } @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { try { BigDecimal input = formatStringToBigDecimal(dest.toString() + source.toString()); if (isInRange(min, max, input)) { return null; } } catch (NumberFormatException nfe) { } return ""; } private boolean isInRange(BigDecimal a, BigDecimal b, BigDecimal c) { return b.compareTo(a) > 0 ? c.compareTo(a) >= 0 && c.compareTo(b) <= 0 : c.compareTo(b) >= 0 && c.compareTo(a) <= 0; } public static BigDecimal formatStringToBigDecimal(String n) { Number number = null; try { number = getDefaultNumberFormat().parse(n.replaceAll("[^\\d]", "")); BigDecimal parsed = new BigDecimal(number.doubleValue()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_UNNECESSARY); return parsed; } catch (ParseException e) { return new BigDecimal(0); } } private static NumberFormat getDefaultNumberFormat() { NumberFormat nf = NumberFormat.getInstance(Locale.getDefault()); nf.setMinimumFractionDigits(MIN_SIG_FIG); return nf; }
我做了一个简单的方法来设置一个最小/最大的Edittext。 我使用数字键盘,并使用这种方法:
private int limit(EditText x,int z,int limin,int limax){ if( x.getText().toString()==null || x.getText().toString().length()==0){ x.setText(Integer.toString(limin)); return z=0; } else{ z = Integer.parseInt(x.getText().toString()); if(z <limin || z>limax){ if(z<10){ x.setText(Integer.toString(limin)); return z=0; } else{ x.setText(Integer.toString(limax)); return z=limax; } } else return z = Integer.parseInt(x.getText().toString()); } }
该方法接受所有的值,但如果用户的值不符合您的限制,它将被自动设置为最小/最大限制。 例如。 限制limin = 10,如果用户设置8,limax = 80,则自动将10保存到variables,并将EditText设置为10。
Pratik的扩展和Zac的答案。 扎克在他的回答中修正了一个小小的错误。 但我注意到代码不支持负值,它会抛出一个NumberFormatExceptionexception。 要解决这个问题,并允许MIN为负值,请使用以下代码。
在另外两行之间加上这一行(粗体):
newVal = newVal.substring(0,dstart)+ source.toString()+ newVal.substring(dstart,newVal.length());
if(newVal.equalsIgnoreCase(“ – ”)&& min <0)返回null;
int input = Integer.parseInt(newVal);
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { try { // Remove the string out of destination that is to be replaced String newVal = dest.toString().substring(0, dstart) + dest.toString().substring(dend, dest.toString().length()); // Add the new string in newVal = newVal.substring(0, dstart) + source.toString() + newVal.substring(dstart, newVal.length()); //****Add this line (below) to allow Negative values***// if(newVal.equalsIgnoreCase("-") && min < 0)return null; int input = Integer.parseInt(newVal); if (isInRange(min, max, input)) return null; } catch (NumberFormatException nfe) { nfe.printStackTrace(); } return ""; }
请检查这个代码
String pass = EditText.getText().toString(); if(TextUtils.isEmpty(pass) || pass.length < [YOUR MIN LENGTH]) { EditText.setError("You must have x characters in your txt"); return; } //continue processing edittext.setOnFocusChangeListener( new OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if(hasFocus) { // USE your code here }
使用下面的链接了解更多关于edittext和edittextfilteres与文本观察者的细节。
我所看到的@ Patrik的解决scheme和@ Zac的补充,所提供的代码仍然有一个很大的问题:
如果min==3
则不可能input以1或2开头的任何数字(例如:15,23)
如果min>=10
则不可能input任何数字,因为每个数字都必须以1,2,3开始。
根据我的理解,我们不能通过简单的使用类InputFilterMinMax
来实现EditText
值的最小 – 最大限制,至less不能用于最小值,因为当用户input正数时,值越来越大,我们可以很容易地进行实时testing以检查是否达到限制或超出范围并阻止不符合条目。 testing最小值是一个不同的故事,因为我们不能确定用户是否已经完成打字,因此不能确定是否应该封锁。
这不是什么操作系统要求,但为了validation的目的,我已经在我的解决scheme中合并了一个InputFilter
来testing最大值,用OnFocusChangeListener
重新testing最小值,当EditText
失去了焦点,假设用户input完成,这是这样的:
package test; import android.text.InputFilter; import android.text.Spanned; public class InputFilterMax implements InputFilter { private int max; public InputFilterMax(int max) { this.max = max; } public InputFilterMax(String max) { this.max = Integer.parseInt(max); } @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { try { String replacement = source.subSequence(start, end).toString(); String newVal = dest.toString().substring(0, dstart) + replacement +dest.toString().substring(dend, dest.toString().length()); int input = Integer.parseInt(newVal); if (input<=max) return null; } catch (NumberFormatException nfe) { } //Maybe notify user that the value is not good return ""; } }
和OnFocusChangeListenerMin
package test; import android.text.TextUtils; import android.view.View; import android.view.View.OnFocusChangeListener; public class OnFocusChangeListenerMin implements OnFocusChangeListener { private int min; public OnFocusChangeListenerMin(int min) { this.min = min; } public OnFocusChangeListenerMin(String min) { this.min = Integer.parseInt(min); } @Override public void onFocusChange(View v, boolean hasFocus) { if(!hasFocus) { String val = ((EditText)v).getText().toString(); if(!TextUtils.isEmpty(val)){ if(Integer.valueOf(val)<min){ //Notify user that the value is not good } } } } }
然后在Activity中将InputFilterMax
和OnFocusChangeListenerMin
为EditText
注意:您可以在onFocusChangeListener
min和max。
mQteEditText.setOnFocusChangeListener( new OnFocusChangeListenerMin('20'); mQteEditText.setFilters(new InputFilter[]{new InputFilterMax(getActivity(),'50')});
如果你只关心最大限度,那么只需join下面的行
android:maxLength="10"
如果您需要添加最小限制,那么您可以这样做,在这种情况下,最小限制为7.用户被限制在最小和最大限制之间input字符(在8和10之间)
public final static boolean isValidCellPhone(String number){ if (number.length() < 8 || number.length() >10 ) { return false; } else { return android.util.Patterns.PHONE.matcher(number).matches(); } }
如果您还需要限制用户在开始时input01,那么修改如果条件这样
if (!(number.startsWith("01")) || number.length() < 8 || number.length() >10 ) { . . . }
最后调用方法就好
....else if (!(Helper.isValidMobilePhone(textMobileNo))){ Helper.setEditTextError(etMobileNo,"Invalid Mobile Number"); }......
如果你需要-90:90这样的负数的范围,你可以使用这个解决scheme。
public class InputFilterMinMax implements InputFilter { private int min, max; public InputFilterMinMax(int min, int max) { this.min = min; this.max = max; } public InputFilterMinMax(String min, String max) { this.min = Integer.parseInt(min); this.max = Integer.parseInt(max); } @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { try { String stringInput = dest.toString() + source.toString(); int value; if (stringInput.length() == 1 && stringInput.charAt(0) == '-') { value = -1; } else { value = Integer.parseInt(stringInput); } if (isInRange(min, max, value)) return null; } catch (NumberFormatException nfe) { } return ""; } private boolean isInRange(int min, int max, int value) { return max > min ? value >= min && value <= max : value >= max && value <= min; } }
我find了我自己的答案。 现在已经很晚了,但我想和你分享一下。 我实现这个接口:
import android.text.TextWatcher; public abstract class MinMaxTextWatcher implements TextWatcher { int min, max; public MinMaxTextWatcher(int min, int max) { super(); this.min = min; this.max = max; } }
然后在你的活动中以这种方式实现它:
private void limitEditText(final EditText ed, int min, int max) { ed.addTextChangedListener(new MinMaxTextWatcher(min, max) { @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 void afterTextChanged(Editable s) { String str = s.toString(); int n = 0; try { n = Integer.parseInt(str); if(n < min) { ed.setText(min); Toast.makeText(getApplicationContext(), "Minimum allowed is " + min, Toast.LENGTH_SHORT).show(); } else if(n > max) { ed.setText("" + max); Toast.makeText(getApplicationContext(), "Maximum allowed is " + max, Toast.LENGTH_SHORT).show(); } } catch(NumberFormatException nfe) { ed.setText("" + min); Toast.makeText(getApplicationContext(), "Bad format for number!" + max, Toast.LENGTH_SHORT).show(); } } }); }
这是一个非常简单的答案,如果有更好的,请告诉我。
@Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { try { String prefix = dest.toString().substring(0, dstart); String insert = source.toString(); String suffix = dest.toString().substring(dend); String input_string = prefix + insert + suffix; int input = Integer.parseInt(input_string); if (isInRange(min, max, input) || input_string.length() < String.valueOf(min).length()) return null; } catch (NumberFormatException nfe) { } return ""; } private boolean isInRange(int a, int b, int c) { return b > a ? c >= a && c <= b : c >= b && c <= a; }
//仍然有一些问题,但是在这里你可以使用min,max在任何范围(正数或负数)
// in filter calss @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { try { // Remove the string out of destination that is to be replaced int input; String newVal = dest.toString() + source.toString(); if (newVal.length() == 1 && newVal.charAt(0) == '-') { input = min; //allow } else { newVal = dest.toString().substring(0, dstart) + dest.toString().substring(dend, dest.toString().length()); // Add the new string in newVal = newVal.substring(0, dstart) + source.toString() + newVal.substring(dstart, newVal.length()); input = Integer.parseInt(newVal); } //int input = Integer.parseInt(dest.toString() + source.toString()); if (isInRange(min, max, input)) return null; } catch (NumberFormatException nfe) { } return ""; } //also the filler must set as below: in the edit createview // to allow enter number and backspace. et.setFilters(new InputFilter[]{new InputFilterMinMax(min >= 10 ? "0" : String.valueOf(min), max >-10 ? String.valueOf(max) :"0" )}); //and at same time must check range in the TextWatcher() et.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged (Editable editable) { String tmpstr = et.getText().toString(); if (!tmpstr.isEmpty() && !tmpstr.equals("-") ) { int datavalue = Integer.parseInt(tmpstr); if ( datavalue >= min || datavalue <= max) { // accept data ... } } } });
要添加到Pratik的答案,这里是一个修改后的版本,用户也可以input最less2位数字,例如15到100:
import android.text.InputFilter; import android.text.Spanned; public class InputFilterMinMax implements InputFilter { private int min, max; public InputFilterMinMax(int min, int max) { this.min = min; this.max = max; } public InputFilterMinMax(String min, String max) { this.min = Integer.parseInt(min); this.max = Integer.parseInt(max); } @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { try { if(end==1) min=Integer.parseInt(source.toString()); int input = Integer.parseInt(dest.toString() + source.toString()); if (isInRange(min, max, input)) return null; } catch (NumberFormatException nfe) { } return ""; } private boolean isInRange(int a, int b, int c) { return b > a ? c >= a && c <= b : c >= b && c <= a; }}
添加:if(end == 1)min = Integer.parseInt(source.toString());
希望这可以帮助。 请不要无理由地downvote。
接受的答案有错误。
int input = Integer.parseInt(dest.toString() + source.toString());
如果我把光标移到文本的中间,然后input一些内容,那么上面的语句会产生错误的结果。 例如,首先input“12”,然后在1和2之间input“0”,那么上面提到的语句将产生“120”而不是102.我修改这个语句为下面的语句:
String destString = dest.toString(); String inputString = destString.substring(0, dstart) + source.toString() + destString.substring(dstart); int input = Integer.parseInt(inputString);
它在xml中的简单方法:
android:maxLength="4"
如果你需要在XML编辑文本中设置4个字符,使用这个:
<EditText android:id="@+id/tv_date_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:maxLength="4"/>