Java 将EditText筛选器设置为自定义范围内的数字

Java 将EditText筛选器设置为自定义范围内的数字,java,android,filter,android-edittext,range,Java,Android,Filter,Android Edittext,Range,我正在寻找一种方法来限制我在EditText字段中输入的数字,但我遇到了一些障碍 我已经彻底研究了我的问题的解决方案,我将在下面具体说明 我想创建4个不同的EditText字段,每个字段都接受以下范围:(1,24);(80, 200); (1, 999); (40,70) 为简单起见,这些将不是小数(或double/float/long),而只是整数 我研究了以下链接提供的解决方案,并指出了它们的缺点 此解决方案仅告诉我如何将输入的文本限制为仅数字数据。它不提供范围 公认的解决方案确实实现了

我正在寻找一种方法来限制我在EditText字段中输入的数字,但我遇到了一些障碍

我已经彻底研究了我的问题的解决方案,我将在下面具体说明

我想创建4个不同的EditText字段,每个字段都接受以下范围:(1,24);(80, 200); (1, 999); (40,70)

为简单起见,这些将不是小数(或double/float/long),而只是整数

我研究了以下链接提供的解决方案,并指出了它们的缺点

此解决方案仅告诉我如何将输入的文本限制为仅数字数据。它不提供范围

公认的解决方案确实实现了设置范围的目标,但问题是,由于它的实现,它只适用于范围(1,24)和(1999)。问题是,如果我查找间隔(40,70)或(80,200)中的值,我将一次输入一个数字,因此这不起作用。它将拒绝一位数的输入,这使得它对用户不友好

我相信这里接受的解决方案与上面的解决方案有相同的问题,因为它一次只需要一个数字。我考虑在后文本更改下使用相同的方法,而不是在ContextChanged上使用相同的方法,但没有效果

此解决方案包括单击按钮以评估数字是否在给定范围内,因此这将被视为“事后”解决方案。我需要一个实时拒绝用户输入的EditText

非常感谢您的帮助,这可能有助于解决许多其他人显然遇到的问题(阅读评论,其他人似乎想要的范围不是以一位数开始/结束)。

使用Textwatcher, 这里我有一个edittext,我允许用户输入1-24范围内的数字

public class MainActivity extends AppCompatActivity {
EditText et;
    int num1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et= (EditText) findViewById(R.id.edit_text);
        et.addTextChangedListener(textWatcher);

    }
    TextWatcher textWatcher =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(et.getText().length()>0) {
                int num = Integer.parseInt(et.getText().toString());
                if (num>=1 && num<=24)
                {
                    //save the number
                    num1=num;
                }
                else{
                    Toast.makeText(MainActivity.this,"Please enter the code in the range of 1-24",Toast.LENGTH_SHORT).show();
                    et.setText("");
                    num1=-1;
                }
            }
            }

        @Override
        public void afterTextChanged(Editable s) {

        }
    };
}

到目前为止,我找到的最佳答案是基于以下链接中的解决方案,但它有一个缺点:()

缺点是一旦我们不再将输入插入EditText,EditText框就会保留这些值(而不是清除)。

我的(编辑)代码如下:

第一类
InputFilterMax

package test;

import android.text.InputFilter;

import android.text.Spanned;
// more imports

public class InputFilterMax implements InputFilter {

private int max;
private Context context;

public InputFilterMax(Context con, int max) {
    this.max = max;
    this.context = con;
}

public InputFilterMax(Context con, String max) {
    this.max = Integer.parseInt(max);
    this.context = con;
}

@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) {
            Toast.makeText(context, "Number not accepted! Must be below or equal to " + max, Toast.LENGTH_SHORT).show();
            return null; 
        }           
        return "";
    }
}
然后在活动中,我使用以下方法应用过滤器和侦听器:

timeEdit = (EditText)findViewById(R.id.query_time_frame);
timeEdit.setFilters(new InputFilter[]{new InputFilterMax(getApplicationContext(), 24)});        // max limit on time
timeEdit.setOnFocusChangeListener(new OnFocusChangeListenerMin(getApplicationContext(), 1));    // min limit on time

如果有人能帮我解决上一个问题,我们将不胜感激。

您可以尝试使用TextWatcher的PostTextChanged回调。看看我是如何实现它的

private TextWatcher tollTextWatcher = 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) {

        }

        @Override
        public void afterTextChanged(Editable editable) {

            if (editable.length() > 0) {
                int val = Integer.valueOf(editable.toString());
                if (val > MAX_VALUE) {
                    edit_toll.setText("");
                    edit_toll.setError("Rs.1 - Rs.500");
                }
            }
        }
    };

看看这个。我已经讲过了。这是#2。我无法想象一种非常有效的方法来实现实时评估,因为正如你所说,输入一次只输入一位数字。如果您不反对使用微调器,您可以定义要包含的值,只让用户选择一个,但是对于EditText,您可能是s.o.l。我反对使用微调器,因为值的范围很大。根据我的一点经验,我无法想象手机屏幕上的一个微调器可以容纳80-200个范围(包括121个整数)。但感谢您指出这种可能性。(关于#2链接)我还想指出,我已经查看了该页面上未被接受的答案。具体来说,Guerneen4的解决方案和Nacho Garcia的解决方案看起来很有希望。但是,前者不适用于我,后者也不重置值。感谢您花时间编写您的解决方案。我现在正在测试每一个案例,我需要一点时间才能回复你。然而,我想知道“请填写所有字段”的代码。。。那去哪了?如果我想按一个按钮接收数据并转到另一个活动,它会进入按钮侦听器的代码空间吗?我已经测试过了,但它不起作用。它与我以前的解决方案遇到的问题相同——它接受1位数字并拒绝存储,因此我可以为超过1位的数字生成更大的数字。例如,范围80-200不适用于您的实现。
package test;

import android.text.TextUtils;
import android.view.View;
import android.view.View.OnFocusChangeListener;
// more imports

public class OnFocusChangeListenerMin implements OnFocusChangeListener {

private int min;
private Context context;

public OnFocusChangeListenerMin(Context con, int min) {
    this.min = min;
    this.context = con;
}

public OnFocusChangeListenerMin(Context con, String min) {
    this.min = Integer.parseInt(min);
    this.context = con;
}


@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){
                Toast.makeText(context, "Number not accepted! Must be above or equal to " + min, Toast.LENGTH_SHORT).show();
            }

        }
    }
}
}
timeEdit = (EditText)findViewById(R.id.query_time_frame);
timeEdit.setFilters(new InputFilter[]{new InputFilterMax(getApplicationContext(), 24)});        // max limit on time
timeEdit.setOnFocusChangeListener(new OnFocusChangeListenerMin(getApplicationContext(), 1));    // min limit on time
private TextWatcher tollTextWatcher = 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) {

        }

        @Override
        public void afterTextChanged(Editable editable) {

            if (editable.length() > 0) {
                int val = Integer.valueOf(editable.toString());
                if (val > MAX_VALUE) {
                    edit_toll.setText("");
                    edit_toll.setError("Rs.1 - Rs.500");
                }
            }
        }
    };