Limit an EditText from 1 to 100 and include the symbol "%"

I'm making an application that takes the data entered in a EditText and does a certain calculation.

The problem is that I need the field to go from 1 to 100%, but the "mask" I'm using is too simple for that, so it only makes the limitation but goes from 0 to 999 and that's not what I want.

I also can't put the % symbol at the end of this field.

Follows the Code:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.EditText;

import com.github.rtoshiro.util.format.MaskFormatter;
import com.github.rtoshiro.util.format.SimpleMaskFormatter;
import com.github.rtoshiro.util.format.pattern.MaskPattern;
import com.github.rtoshiro.util.format.text.MaskTextWatcher;

public class ActivityForm extends AppCompatActivity {


private EditText percentual;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_activity_form);

    percentual = (EditText) findViewById(R.id.percentual_Id);
    SimpleMaskFormatter simpleMaskPercentual = new SimpleMaskFormatter( " NNN% " );
    MaskTextWatcher maskPercentual = new MaskTextWatcher(percentual, simpleMaskPercentual);
    percentual.addTextChangedListener( maskPercentual );
    }
}
Author: Victor Stafusa, 2018-07-26

1 answers

Parsing the MaskFormatter code on GitHub , I think the easiest approach is to implement TextWatcher directly. The MaskFormatter does not seem to have been made for a case like the one you have.

I'm going to use a regular expression-based approach. The idea is that it validates the input according to a regular expression. If the input is invalid, discard the last character and try again until the resulting string is valid or becomes empty. That's what the method format(String) below does.

The substitute I think would be this:

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import android.widget.TextView;
import java.util.regex.Pattern;

public class ActivityForm extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_activity_form);
        EditText percentual = (EditText) findViewById(R.id.percentual_Id);
        PercentTextWatcher mask = new PercentTextWatcher(percentual);
        percentual.addTextChangedListener(mask);
    }

    private static class PercentTextWatcher implements TextWatcher {

        private static final Pattern PERC_PAT =
                Pattern.compile("(?:[1-9]|[1-9][0-9]|100)%?");

        private final TextView textView;

        private String currentText;

        public PercentTextWatcher(TextView textView) {
            this.regex = regex;
        }

        @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.toString().equals(currentText)) {
                currentText = formatter.format(charSequence.toString());
                textView.setText(currentText);
                if (textView instanceof EditText) {
                    EditText editText = (EditText) textView;
                    editText.setSelection(currentText.length());
                }
            }
        }

        @Override
        public void afterTextChanged(Editable editable) {
        }

        private static String format(String in) {
            if (in == null) return "";
            for (String s = in; !s.isEmpty(); s = s.substring(0, s.length() - 1)) {
                if (PERC_PAT.matcher(s).matches()) return s;
            }
            return "";
        }
    }
}

Here is a test of the format(String) method of the code above.

Note that there are two classes in this file. The Class PercentTextWatcher is used to replace the MaskTextWatcher.

If you prefer to use 0% to 100% instead of 1% to 100%, just change the regular expression to "(?:[0-9]|[1-9][0-9]|100)%?" instead of "(?:[1-9]|[1-9][0-9]|100)%?".

 1
Author: Victor Stafusa, 2018-07-27 01:02:32