我想为EditText
定义最小值和最大值。
例如:如果有人试图在其中输入月份值,则该值必须介于1-12之间。
我可以使用TextWatcher
来完成,但我想知道在布局文件或其他地方是否有其他方法可以做到这一点。
编辑:
我不想限制字符数。我想限制价值。例如,如果我在输入12时限制月EditText
个字符,它将接受它,但如果我输入22,则在我进入时不得接受它。
答案 0 :(得分:253)
首先制作这个课程:
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")});
这样,用户只需输入1到12的值。
编辑:
使用android:inputType="number"
设置编辑文字。
感谢。
答案 1 :(得分:77)
Pratik的代码中存在一个小错误。例如,如果值为10并且您在开头添加1以使其为110,则过滤器函数会将新值视为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 "";
}
答案 2 :(得分:9)
扩展Pratik和Zac的答案。 Zac在他的回答中修复了一个Pratik的小虫子。但我发现代码不支持负值,它会抛出NumberFormatException。要解决此问题,并允许MIN为负数,请使用以下代码。
在另外两行之间添加此行(粗体):
newVal = newVal.substring(0,dstart)+ source.toString()+ newVal.substring(dstart,newVal.length());
if(newVal.equalsIgnoreCase(&#34; - &#34;)&amp;&amp; min&lt; 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 "";
}
答案 3 :(得分:8)
在@ Patrik的解决方案和@Zac的补充中,我所看到的代码仍然存在很大问题:
如果min==3
则无法输入以1或2开头的任何数字(例如:15,23)
如果min>=10
那么就不可能输入任何内容,因为每个数字都必须以1,2,3 ...
根据我的理解,我们无法通过简单使用类EditText
来实现InputFilterMinMax
值的最小 - 最大限制,至少不能达到最小值,因为当用户键入时正数,值越来越大,我们可以轻松地执行即时测试,以检查它是否达到限制或超出范围并阻止不符合条目。测试最小值是一个不同的故事,因为我们无法确定用户是否已完成输入,因此无法确定是否应该阻止。
这不是OP所要求的,但出于验证目的,我在我的解决方案中合并InputFilter
以测试最大值,OnFocusChangeListener
在{{1}时重新测试最小值假设用户输入完成后失去了焦点,它就像这样:
EditText
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
}
}
}
}
}
和InputFilterMax
设置为OnFocusChangeListenerMin
注意:您可以在EditText
中同时使用最小值和最大值。
onFocusChangeListener
答案 4 :(得分:5)
我将@Pratik Sharmas代码扩展为使用BigDecimal对象而不是整数,以便它可以接受更大的数字,并在EditText中考虑任何不是数字的格式(如货币格式,即空格,逗号和句点)< / p>
编辑:请注意,此实现有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;
}
答案 5 :(得分:5)
如果您需要带负数的范围,例如-90:90,则可以使用此解决方案。
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;
}
}
答案 6 :(得分:4)
接受的答案有问题。
int input = Integer.parseInt(dest.toString() + source.toString());
如果我将光标移动到文本的中间,然后键入内容,那么上面的语句将产生错误的结果。 例如,首先键入“12”,然后在1和2之间键入“0”,则上面提到的语句将产生“120”而不是102。 我将此声明修改为以下声明:
String destString = dest.toString();
String inputString = destString.substring(0, dstart) + source.toString() + destString.substring(dstart);
int input = Integer.parseInt(inputString);
答案 7 :(得分:3)
我提出了一种更简单的方法来将最小值/最大值设置为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());
}
}
该方法接受您的所有值,但如果用户的值不符合您的限制,则会自动设置为最小/最大限制。 对于前者limit limin = 10,如果用户设置为8,则limax = 80,自动将10保存到变量,EditText设置为10.
答案 8 :(得分:3)
我找到了自己的答案。现在已经很晚了,但我想和你分享。 我实现了这个接口:
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();
}
}
});
}
这是一个非常简单的答案,如果有更好的请告诉我。
答案 9 :(得分:2)
@Patrik的代码是个不错的主意,但有很多错误。 @Zac和@Anthony B(负数解决方案)解决了其中一些问题,但是@Zac的代码仍然存在3个市长错误:
1。。如果用户删除EditText中的所有条目,则无法再次键入任何数字。当然,可以使用每个字段上的EditText更改的侦听器来控制此操作,但是它将清除掉为应用程序中的每个EditText使用通用InputFilter类的美妙之处。
2 。@ Guernee4说,例如,如果min = 3,则不可能输入任何以1开头的数字。
3。。例如,如果min = 0,则您可以输入希望包含多个零,这表示结果不理想。或者,无论最小值是多少,用户都可以将光标放置在第一个数字的左侧,左端放置一堆前导零,这也不美观。
我想出了@Zac代码的这些小改动,以解决这3个错误。关于错误3,我仍然无法完全删除左侧的所有前导零。它始终可以是一个,但是在这种情况下,00、01、0100等比000000、001、000100等更有效。等等
代码如下:
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
try {
// Using @Zac's initial solution
String lastVal = dest.toString().substring(0, dstart) + dest.toString().substring(dend);
String newVal = lastVal.substring(0, dstart) + source.toString() + lastVal.substring(dstart);
int input = Integer.parseInt(newVal);
// To avoid deleting all numbers and avoid @Guerneen4's case
if (input < min && lastVal.equals("")) return String.valueOf(min);
// Normal min, max check
if (isInRange(min, max, input)) {
// To avoid more than two leading zeros to the left
String lastDest = dest.toString();
String checkStr = lastDest.replaceFirst("^0+(?!$)", "");
if (checkStr.length() < lastDest.length()) return "";
return null;
}
} catch (NumberFormatException ignored) {}
return "";
}
祝你有美好的一天!
答案 10 :(得分:2)
chunked
答案 11 :(得分:1)
请检查此代码
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的更多详细信息..
答案 12 :(得分:1)
科特林(如果有需要的话)(使用实用程序)
class InputFilterMinMax: InputFilter {
private var min:Int = 0
private var max:Int = 0
constructor(min:Int, max:Int) {
this.min = min
this.max = max
}
constructor(min:String, max:String) {
this.min = Integer.parseInt(min)
this.max = Integer.parseInt(max)
}
override fun filter(source:CharSequence, start:Int, end:Int, dest: Spanned, dstart:Int, dend:Int): CharSequence? {
try
{
val input = Integer.parseInt(dest.toString() + source.toString())
if (isInRange(min, max, input))
return null
}
catch (nfe:NumberFormatException) {}
return ""
}
private fun isInRange(a:Int, b:Int, c:Int):Boolean {
return if (b > a) c in a..b else c in b..a
}
}
然后在您的Kotlin课堂上使用它
percentage_edit_text.filters = arrayOf(Utilities.InputFilterMinMax(1, 100))
此EditText允许1到100。
然后从您的XML中使用它
android:inputType="number"
答案 13 :(得分:1)
关于Kotlin的非常简单的示例:
import android.text.InputFilter
import android.text.Spanned
class InputFilterRange(private var range: IntRange) : InputFilter {
override fun filter(source: CharSequence, start: Int, end: Int, dest: Spanned, dstart: Int, dend: Int) = try {
val input = Integer.parseInt(dest.toString() + source.toString())
if (range.contains(input)) null else ""
} catch (nfe: NumberFormatException) {
""
}
}
答案 14 :(得分:1)
@Pratik Sharma
要获得支持 负数 ,请在过滤器方法内添加以下代码:
package ir.aboy.electronicarsenal;
import android.text.InputFilter;
import android.text.Spanned;
public class InputFilterMinMax implements InputFilter {
private int min, max;
int input;
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 ((dest.toString() + source.toString()).equals("-")) {
source = "-1";
}
input = Integer.parseInt(dest.toString() + source.toString());
if (isInRange(min, max, input))
return null;
} catch (NumberFormatException ignored) {
}
return "";
}
private boolean isInRange(int a, int b, int c) {
return b > a ? c >= a && c <= b : c >= b && c <= a;
}
}
然后在“活动”中使用它:
findViewById(R.id.myEditText).setFilters(new InputFilter[]{ new InputFilterMinMax(1, 12)});
设置您的编辑文本:
android:inputType="number|numberSigned"
答案 15 :(得分:1)
如果您只关心最大限制,那么只需添加以下行
android:maxLength="10"
如果您需要添加最小限制,那么您可以这样做,在这种情况下,最小限制是7.用户被限制在最小和最大限制之间输入字符(在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();
}
}
如果你还需要限制用户在开始时输入01,那么修改if条件就像这样
if (!(number.startsWith("01")) || number.length() < 8 || number.length() >10 ) {
.
.
.
}
在结束通话方法如
....else if (!(Helper.isValidMobilePhone(textMobileNo))){
Helper.setEditTextError(etMobileNo,"Invalid Mobile Number");
}......
答案 16 :(得分:0)
这是我使用的方式,它正在为负数工作
首先,使用以下代码创建MinMaxFIlter.java类:
import android.text.InputFilter;
import android.text.Spanned;
import android.util.Log;
/**
* Created by 21 on 4/5/2016.
*/
public class MinMaxFilter implements InputFilter {
private double mIntMin, mIntMax;
public MinMaxFilter(double minValue, double maxValue) {
this.mIntMin = minValue;
this.mIntMax = maxValue;
}
public MinMaxFilter(String minValue, String maxValue) {
this.mIntMin = Double.parseDouble(minValue);
this.mIntMax = Double.parseDouble(maxValue);
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
try {
Boolean isNeg = false;
String provi = dest.toString() + source.toString();
if("-".equals(provi.substring(0,1))){
if(provi.length()>1) {
provi = provi.substring(1, provi.length());
isNeg = true;
}
else{
if("".equals(source)){
return null;
}
return "-";
}
}
double input = Double.parseDouble(provi);
if(isNeg){input = input * (-1);}
if (isInRange(mIntMin, mIntMax, input)) {
return null;
}
} catch (Exception nfe) {}
return "";
}
private boolean isInRange(double a, double b, double c) {
if((c>=a && c<=b)){
return true;
}
else{
return false;
}
}
}
然后,创建并将过滤器设置为您的edittext,如下所示:
EditText edittext = new EditText(context);
editext.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
eInt.setFilters(new InputFilter[]{new MinMaxFilter(min, max)});
答案 17 :(得分:0)
这是我的代码max = 100,min = 0
XML
<TextView
android:id="@+id/txt_Mass_smallWork"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000"
android:textSize="20sp"
android:textStyle="bold" />
的java
EditText ed = findViewById(R.id.txt_Mass_smallWork);
ed.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {`
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if(!charSequence.equals("")) {
int massValue = Integer.parseInt(charSequence.toString());
if (massValue > 10) {
ed.setFilters(new InputFilter[]{new InputFilter.LengthFilter(2)});
} else {
ed.setFilters(new InputFilter[]{new InputFilter.LengthFilter(3)});
}
}
}
@Override
public void afterTextChanged(Editable editable) {
}
});
答案 18 :(得分:0)
我知道已经有一百万个答案,其中一个被接受了。但是,接受的答案中存在许多错误,其余大多数只是修复了其中一个(或两个),而没有扩展到所有可能的用例。
所以我基本上编译了支持答案中建议的大多数错误修复,并添加了一个方法,允许在0方向范围之外连续输入数字(如果范围不是从0开始) ,至少在它确定它不能再在该范围内之前。因为要清楚,这是唯一一个真正给许多其他解决方案带来麻烦的时候。
以下是修复:
public class InputFilterIntRange implements InputFilter, View.OnFocusChangeListener {
private final int min, max;
public InputFilterIntRange(int min, int max) {
if (min > max) {
// Input sanitation for the filter itself
int mid = max;
max = min;
min = mid;
}
this.min = min;
this.max = max;
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
// Determine the final string that will result from the attempted input
String destString = dest.toString();
String inputString = destString.substring(0, dstart) + source.toString() + destString.substring(dstart);
// Don't prevent - sign from being entered first if min is negative
if (inputString.equalsIgnoreCase("-") && min < 0) return null;
try {
int input = Integer.parseInt(inputString);
if (mightBeInRange(input))
return null;
} catch (NumberFormatException nfe) {}
return "";
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
// Since we can't actively filter all values
// (ex: range 25 -> 350, input "15" - could be working on typing "150"),
// lock values to range after text loses focus
if (!hasFocus) {
if (v instanceof EditText) sanitizeValues((EditText) v);
}
}
private boolean mightBeInRange(int value) {
// Quick "fail"
if (value >= 0 && value > max) return false;
if (value >= 0 && value >= min) return true;
if (value < 0 && value < min) return false;
if (value < 0 && value <= max) return true;
boolean negativeInput = value < 0;
// If min and max have the same number of digits, we can actively filter
if (numberOfDigits(min) == numberOfDigits(max)) {
if (!negativeInput) {
if (numberOfDigits(value) >= numberOfDigits(min) && value < min) return false;
} else {
if (numberOfDigits(value) >= numberOfDigits(max) && value > max) return false;
}
}
return true;
}
private int numberOfDigits(int n) {
return String.valueOf(n).replace("-", "").length();
}
private void sanitizeValues(EditText valueText) {
try {
int value = Integer.parseInt(valueText.getText().toString());
// If value is outside the range, bring it up/down to the endpoint
if (value < min) {
value = min;
valueText.setText(String.valueOf(value));
} else if (value > max) {
value = max;
valueText.setText(String.valueOf(value));
}
} catch (NumberFormatException nfe) {
valueText.setText("");
}
}
}
请注意,某些输入案例无法处理&#34;积极&#34; (即,当用户输入它时),因此我们必须忽略它们并在用户完成文本编辑后处理它们。
以下是您可以使用它的方法:
EditText myEditText = findViewById(R.id.my_edit_text);
InputFilterIntRange rangeFilter = new InputFilterIntRange(25, 350);
myEditText.setFilters(new InputFilter[]{rangeFilter});
// Following line is only necessary if your range is like [25, 350] or [-350, -25].
// If your range has 0 as an endpoint or allows some negative AND positive numbers,
// all cases will be handled pre-emptively.
myEditText.setOnFocusChangeListener(rangeFilter);
现在,当用户尝试输入的数字接近于范围允许的0时,将会发生以下两种情况之一:
如果min
和max
的数字位数相同,那么一旦他们到达最后的数字,就不会允许他们输入数字。
如果当文字失去焦点时,该字段之外的数字会留在字段中,它将自动调整到最近的边界。
当然,永远不会允许用户输入比范围允许更远的0的值,也不允许输入这样的数字,而不是偶然的&#34;因此,请在文本字段中。
已知问题(s?)
EditText
失去焦点时,此方法才有效。 另一种选择是在用户点击&#34;完成&#34; /返回键时进行消毒,但在很多甚至大多数情况下,这会导致焦点丢失。
然而,关闭软键盘将不自动取消对焦元素。我确信99.99%的Android开发人员希望它(并且EditText
元素上的焦点处理通常不是一个泥潭),但到目前为止还没有内置的功能。如果您需要,我发现的解决此问题的最简单方法是扩展EditText
这样的内容:
public class EditTextCloseEvent extends AppCompatEditText {
public EditTextCloseEvent(Context context) {
super(context);
}
public EditTextCloseEvent(Context context, AttributeSet attrs) {
super(context, attrs);
}
public EditTextCloseEvent(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
for (InputFilter filter : this.getFilters()) {
if (filter instanceof InputFilterIntRange)
((InputFilterIntRange) filter).onFocusChange(this, false);
}
}
return super.dispatchKeyEvent(event);
}
}
这将&#34;技巧&#34;即使视图没有实际失去焦点,过滤器也会清理输入。如果视图后来失去焦点,输入卫生将再次触发,但没有任何改变,因为它已经修复。
<强>合强>
呼。那是很多。最初看起来像是一个非常简单的问题最终发现了许多丑陋的香草Android(至少在Java中)。再一次,如果你的范围在某种程度上不包括0,你只需要添加监听器并扩展EditText
。(实际上,如果你的范围不包括0但是从1或-1开始,你也不会遇到问题。)
最后一点,这仅适用于整理。肯定有一种方法可以实现它来处理小数(double
,float
),但既然我和原始提问者都不需要这些,我也不是特别想得到一切都深入其中。简单地使用完成后过滤和以下几行非常容易:
// Quick "fail"
if (value >= 0 && value > max) return false;
if (value >= 0 && value >= min) return true;
if (value < 0 && value < min) return false;
if (value < 0 && value <= max) return true;
您只需要从int
更改为float
(或double
),允许插入一个.
(或,
,具体取决于country?),并解析为十进制类型之一而不是int
。
无论如何,它处理大部分工作,因此它的工作方式非常相似。
答案 19 :(得分:0)
要添加到Pratik的答案,这里是一个修改版本,用户也可以输入最小2位数,例如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());
希望这会有所帮助。 请不要无缘无故地投票。
答案 20 :(得分:0)
您可以使用InputFilter进行此操作。显然,这只是您可以使用的输入过滤器接口。在创建扩展输入过滤器的新类的烦人方法之前,您可以将此快捷方式与内部类接口实例化结合使用。
因此,您只需执行以下操作:
EditText subTargetTime = (EditText) findViewById(R.id.my_time);
subTargetTime.setFilters( new InputFilter[] {
new InputFilter() {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
int t = Integer.parseInt(source.toString());
if(t <8) { t = 8; }
return t+"";
}
}
});
在此示例中,我检查EditText的值是否大于8。如果不是,则应将其设置为8。因此,很显然,您需要自己自己决定max max或任何过滤器逻辑。但是至少您可以将过滤器逻辑编写得很整齐,简短,直接写入EditText。
希望这会有所帮助
答案 21 :(得分:0)
要定义EditText的最小值,请使用以下方法:
if (message.trim().length() >= 1 && message.trim().length() <= 12) {
// do stuf
} else {
// Too short or too long
}
答案 22 :(得分:0)
//仍有一些问题,但在这里你可以在任何范围内使用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 ...
}
}
}
});
答案 23 :(得分:0)
我在做一个宠物项目时偶然发现了这个问题。 我已经在这里阅读了一些答案,并且可能在我的代码中采用了其中的一两个。
坏消息:我设法通过一种非常肮脏的方式来做到这一点(您会明白为什么)。还有一些我一直不愿意解决的错误(我在凌晨2点写这个),例如,如果min
的值为10,您将无法输入数字开头。
好消息:我设法摆脱了@nnyerges提到的前导零错误,仅使用InputFilter
减小到一个0,即{{1 }}的值是0。但是,min
的实现限制是在用户删除后跟零的第一个数字时出现的,例如如果首先用户输入InputFilter
,然后删除1000
,则它将变为1
。这很丑陋,这就是我对000
/ TextChangedListener
的肮脏丑陋出现的地方。(我知道OP已经说过他可以使用TextWatcher
来做到这一点,但是不管怎样。)
使用TextWatcher
的另一个限制(或 MY 限制?)是InputFilter
为inputType
时,这意味着用户可以输入小数点分隔符。例如:范围是numberDecimal
,用户输入0 - 100
,然后用户删除分隔符,我们将得到99.99
。我们不想那样吗?
我也做到了适应负值。
我的代码中的某些功能(无论您是否喜欢)都包括微不足道的9999
,例如如果用户从0
中删除1
,只要它在定义的范围内,它将修剪前10032
个,因此最终结果将是32。其次,当用户尝试删除负号(0
)或小数点分隔符(-
),它将检查删除后的结果数是否仍在范围内。如果不是,则它将恢复为上一个值。换句话说,不允许用户进行这种删除。 但是,如果您希望在发生这种情况时将新值设置为.
或min
值,也可以这样做。
注意::我懒得连本地化都打扰了,因此使用逗号作为小数点分隔符的人必须自己手动更改。
第二个注意事项:该代码非常凌乱,可能有一些或很多冗余检查,因此请注意。另外,如果您有建议,请随时发表评论,因为我也想改进它。我将来可能需要使用它。谁知道?
反正就这样。
max
现在,最脏的部分:
import android.text.InputFilter;
import android.text.Spanned;
import android.util.Log;
public class InputFilterMinMax implements InputFilter {
private double min, max;
public InputFilterMinMax(double min, double max) {
this.min = min;
this.max = max;
}
public InputFilterMinMax(String min, String max) {
this.min = Double.parseDouble(min);
this.max = Double.parseDouble(max);
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
try {
String lastVal = dest.toString();
String newVal = lastVal.substring(0, dstart) + source.toString() + lastVal.substring(dstart);
String strInput = source.toString();
double input;
if (strInput.equals("-") && (lastVal.length() == 0 || lastVal.equals("0"))) {
return null;
} else {
input = Double.parseDouble(newVal);
}
if (isInRange(min, max, input)) {
try {
if (lastVal.equals("0") && strInput.equals("0") && !strInput.equals(".")) {
Log.d("Checkpoint 1", "Can't put 0 again.");
return "";
} else if (strInput.equals("0")) {
if (dstart == 0) {
if (lastVal.substring(0, 1).equals("0")) {
Log.d("Checkpoint 2", "Can't put 0 again.");
return "";
} else if (!lastVal.substring(0, 1).equals(".")) {
Log.d("Checkpoint 3", "Can't put 0 in front of them.");
return "";
}
} else {
if (lastVal.substring(0, 1).equals("0") && dstart == 1) {
Log.d("Checkpoint 4", "Can't put 0 again.");
return "";
} else if (lastVal.substring(0, 1).equals("-")) {
if (Double.parseDouble(lastVal) == 0) {
if (!lastVal.contains(".")) {
Log.d("Checkpoint 5", "Can't put 0 here.");
return "";
} else {
if (dstart <= lastVal.indexOf(".")) {
Log.d("Checkpoint 6", "Can't put 0 here.");
return "";
}
}
} else {
if (lastVal.indexOf("0") == 1 && (dstart == 1 || dstart == 2)) {
Log.d("Checkpoint 7", "Can't put 0 here.");
return "";
} else if ((!lastVal.substring(1, 2).equals("0") && !lastVal.substring(1, 2).equals(".")) && dstart == 1) {
Log.d("Checkpoint 8", "Can't put 0 here.");
return "";
}
}
}
}
}
/**
* If last value is a negative that equals min value,
* and user tries to input a decimal separator at the
* very end, ignore it, because they won't be able to
* input anything except 0 after that anyway.
*/
if (strInput.equals(".") && lastVal.substring(0,1).equals("-")
&& Double.parseDouble(lastVal) == min && dstart == lastVal.length()) {
return "";
}
} catch (Exception e) {
}
return null;
}
} catch (Exception ignored) {
ignored.printStackTrace();
}
return "";
}
private boolean isInRange(double a, double b, double c) {
return b > a ? c >= a && c <= b : c >= b && c <= a;
}
}
答案 24 :(得分:0)
private InputFilter inRange(int min, int max) {
return new InputFilter(){
@Override
public CharSequence filter(CharSequence source, int start1, int end, Spanned dest, int dstart, int dend) {
try {
int input = Integer.parseInt(dest.toString() + source.toString());
if (input < min || input > max){
return "";
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
};
}
edittext1.setFilters(new InputFilter[]{inRange(3,60)});
edittext2.setFilters(new InputFilter[]{inRange(1,100)});
您可以制作更多的文件管理器并像这样添加:
edittext1.setFilters(new InputFilter[]{filter1(somevalue),filter2(somevalue)});
答案 25 :(得分:0)
这里的许多解决方案都很棒,但我想提供一个更快的替代方案,如果您只是在寻找一种防止溢出的方法,这可能就足够了:
android:maxLength="9"
这将确保您不会在非小数的 32 位整数上溢出。所以这里的最小值是 -99999999
,最大值是 999999999
。
答案 26 :(得分:-1)
这是我对Pratik Sharma对Kotlin
和Double
的回答,如果有人需要的话
class InputFilterMinMax : InputFilter {
private var min: Double = MIN_LIMIT
private var max: Double = MIN_LIMIT
constructor(min: Int, max: Int) {
this.min = min.toDouble()
this.max = max.toDouble()
}
constructor(min: String, max: String) {
this.min = min.toDouble()
this.max = max.toDouble()
}
constructor(min: Double, max: Double) {
this.min = min
this.max = max
}
override fun filter(
source: CharSequence,
start: Int,
end: Int,
dest: Spanned,
dstart: Int,
dend: Int
): CharSequence? {
try {
val input = (dest.toString() + source.toString()).toDouble()
if (isInRange(min, max, input))
return null
} catch (nfe: NumberFormatException) {
Timber.e(nfe)
}
return ""
}
private fun isInRange(a: Double, b: Double, c: Double): Boolean {
return if (b > a) c in a..b else c in b..a
}
}