0

I want to have an edit text that only allows the user to enter a given number of text, for my case I want 16 digits, and then group them in pairs of 4. I have already set the text limit. Currently my code looks like this,

<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:counterEnabled="true"
    app:counterMaxLength="16">

    <EditText
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter Code"
        android:inputType="number" />
</android.support.design.widget.TextInputLayout>

But now my question is how to group them. I want my final output to be something like this XXXX-XXXX-XXXX-XXXX-. Kind a way a product key looks like.

Vladimir Markeev
  • 654
  • 10
  • 25
Nixon Kosgei
  • 788
  • 8
  • 13
  • check this same solution http://stackoverflow.com/questions/5947674/custom-format-edit-text-input-android-to-accept-credit-card-number – Android Surya Jul 25 '16 at 07:30

2 Answers2

2

You can try with the code below, it works well :

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "my_log";
    static final Pattern CODE_PATTERN = Pattern.compile("([0-9]{0,4})|([0-9]{4}-)+|([0-9]{4}-[0-9]{0,4})+");

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final EditText editText = (EditText) findViewById(R.id.editText);
        editText.addTextChangedListener(new TextWatcher() {

            @Override
            public void afterTextChanged(Editable s) {
                Log.d(TAG, "input" + s.toString());

                if (s.length() > 0 && !CODE_PATTERN.matcher(s).matches()) {
                    String input = s.toString();
                    String numbersOnly = keepNumbersOnly(input);
                    String code = formatNumbersAsCode(numbersOnly);

                    Log.d(TAG, "numbersOnly" + numbersOnly);
                    Log.d(TAG, "code" + code);

                    editText.removeTextChangedListener(this);
                    editText.setText(code);
                    editText.setSelection(code.length());
                    editText.addTextChangedListener(this);
                }
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            private String keepNumbersOnly(CharSequence s) {
                return s.toString().replaceAll("[^0-9]", "");
            }

            private String formatNumbersAsCode(CharSequence s) {
                int groupDigits = 0;
                String tmp = "";
                for (int i = 0; i < s.length(); ++i) {
                    tmp += s.charAt(i);
                    ++groupDigits;
                    if (groupDigits == 4) {
                        tmp += "-";
                        groupDigits = 0;
                    }
                }
                return tmp;
            }
        });
    }

}
Dang Nguyen
  • 354
  • 2
  • 9
0

You have two options:

  1. Add a TextWatcher to the EditText. Then after every character additon, evaluate the contents and add the dashes as needed. This is the quicker solution.

  2. Have a look at EditText sourcecode (depensing on the API level, it may also be in the sourcecode of the super class of EditText, Textview). Study its onDraw() metchod and then implement your own class extending EditText, which will draw the text as you want it. This will take more time, but the getText() method will return the raw input, without dashes.

Kelevandos
  • 7,024
  • 2
  • 29
  • 46