0

I want the user to change some device settings, for example run an alarm after X seconds (default 5s). I want the user to be able to type in what they want (number value from the edit text), but if the value they put in is not between 2s and 20s, I want the edit text to default back to 5s.

Whats the best way to do this? I tried with a watcher but i think I'm running into an infinite loop.

//Settings distance edit text
settings_distance_edit.addTextChangedListener(new TextWatcher() {
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        int settings_distance_edit_value = Integer.parseInt(settings_distance_edit.getText().toString()+"");
        if (settings_distance_edit_value >= DISTANCE_MIN && settings_distance_edit_value <= DISTANCE_MAX) {
            Log.v("Tag", settings_distance_edit_value+"");

        } else {
            settings_distance_edit.setText(DISTANCE_DEFAULT+"");
        }
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        // TODO Auto-generated method stub
    }

    @Override
    public void afterTextChanged(Editable s) {

    }
});
letsintegreat
  • 3,328
  • 4
  • 18
  • 39

4 Answers4

1

i guess you can do it this way

  • You can check for the value without using TextWatcher
    int settings_distance_edit_value = Integer.parseInt(settings_distance_edit.getText().toString()+"");
       if (settings_distance_edit_value >= DISTANCE_MIN && settings_distance_edit_value <= DISTANCE_MAX) {
          // you set your default value
     settings_distance_edit.setText("5s");

       } else {
           settings_distance_edit.setText(DISTANCE_DEFAULT+"");
       }
Taki
  • 3,290
  • 1
  • 16
  • 41
1

Try InputFilter

public class InputFilterMinMax implements InputFilter
{
    private final int min;
    private final int max;
    private final UtilityListener utilityListener;

    public InputFilterMinMax(int min, int max,UtilityListener utilityListener)
    {
        this.min = min;
        this.max = max;
        this.utilityListener = utilityListener;
    }

    @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;
            }
            else
            {
                utilityListener.getItem("Value cannot exceed " + max);
            }
        }
        catch (NumberFormatException ignored)
        {
            utilityListener.getItem("NumberFormatException");
        }
        return "";
    }

    private boolean isInRange(int a, int b, int c)
    {
    return b > a ? c >= a && c <= b : c >= b && c <= a;
    }
}

Activity Code

binding.editText.setFilters(new InputFilter[]{new InputFilterMinMax(1,10,object ->
        {
            String message = (String) object;

            Toast.makeText(MainActivity.this,message,Toast.LENGTH_SHORT).show();
        })});

Listener

public interface UtilityListener
{
    void getItem(Object object);
}
Shashank
  • 111
  • 6
1
1.for integer input set your EditText digits="0123456789"
2. In if condition you should use || condition instead of &&
3. also check if input is not empty as given below.

this is working fine ,no infinite loop





   var MIN=2 
   var MAX=20 
   var DEF=5 
   et_distance.addTextChangedListener(object : TextWatcher { 
     override fun   onTextChanged(s: CharSequence?, start: Int,
     before: Int, count: Int) {

            if (et_distance.text.toString().isNotEmpty()) {
                var etValue = et_distance.text.toString().toInt()

                if (etValue >= MAX || etValue <= MIN){ 
                
                  
             et_distance.setText(DEF.toString())
               
             }
                else {
                   Log.d("TAG", "onTextChanged: $etValue")
                     }
            }
        }
        override fun beforeTextChanged(s: CharSequence?, 
                        start:Int,count: Int,  after: Int) {
        }
        override fun afterTextChanged(s: Editable?) {
        }

    })
Antier Solutions
  • 1,326
  • 7
  • 10
1

You should not use addTextChangedListener() for this purpose. You should wait for the user to hit the enter or done key on their keyboard. This can be achieved by the below code:

settings_distance_edit.setOnEditorActionListener(new TextView.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE || event != null && event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
                if (event == null || !event.isShiftPressed()) {
                   // the user is done typing and has submitted the input. 

                   // your code
                   int settings_distance_edit_value = Integer.parseInt(settings_distance_edit.getText().toString()+"");
                   if (settings_distance_edit_value >= DISTANCE_MIN && settings_distance_edit_value <= DISTANCE_MAX) {
                      Log.v("Tag", settings_distance_edit_value+"");

                   } else {
                      settings_distance_edit.setText(DISTANCE_DEFAULT+"");
                   }

                   return true;
                }                
            }
            return false; // the user has not submitted the input yet. 
    }
});
Simran Sharma
  • 852
  • 7
  • 16