Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make an Edittext with an underline for character for a fix size String in Android?

I need to make a EditText that replace one underline for a char when the user adds new one. Something like this:

enter image description here

I make something similar, with 6 EditTexts (the size of the String needed) and a '_' char for the hint, a when writing in one a change the focus to the next and when deleting change the focus to the previuos, but I have problems when deleting or editing not the last char added. Anyone knows how can I to do it well?

This is my code in the activity:

   private void manageFocus(final EditText beforeET, final EditText currenteET, final EditText afterET) {

       if (beforeET != null) {
           currenteET.setOnFocusChangeListener(new View.OnFocusChangeListener() {
               @Override
               public void onFocusChange(View v, boolean hasFocus) {
                   if (hasFocus && beforeET != null && beforeET.getText().toString().length() < 1 && currenteET.getText().toString().equals("")) {
                       beforeET.requestFocus();
                   }
               }
           });
       }

       currenteET.addTextChangedListener(new TextWatcher() {
           @Override
           public void beforeTextChanged(CharSequence s, int start, int count, int after) {
           }

           @Override
           public void afterTextChanged(Editable s) {

           }

           @Override
           public void onTextChanged(CharSequence s, int start, int before, int count) {
               if (afterET != null && currenteET.getText().toString().length() >= 1) {
                   afterET.requestFocus();
               } else if (beforeET != null && currenteET.getText().toString().length() < 1) {
                   beforeET.requestFocus();
               }
           }
       });
   }

And the layout code is this:

<LinearLayout
android:id="@+id/login_layout_code"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:visibility="gone">

<EditText
android:id="@+id/login_code_et01"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:hint="_"
android:textColorHint="@color/text_gray"
android:gravity="center"
android:textSize="@dimen/textsize_32"
android:inputType="number"
android:maxLength="1"
android:textColor="@color/text_gray"
fontPath="fonts/TitilliumText/TitilliumText22L-Bold.otf"/>

<EditText
android:id="@+id/login_code_et02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="_"
android:textColorHint="@color/text_gray"
android:textSize="@dimen/textsize_32"
android:layout_toRightOf="@id/login_code_et01"
android:inputType="number"
android:maxLength="1"
android:textColor="@color/text_gray"
fontPath="fonts/TitilliumText/TitilliumText22L-Bold.otf"/>

<EditText
android:id="@+id/login_code_et03"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="_"
android:textColorHint="@color/text_gray"
android:textSize="@dimen/textsize_32"
android:layout_toRightOf="@id/login_code_et02"
android:inputType="number"
android:maxLength="1"
android:textColor="@color/text_gray"
fontPath="fonts/TitilliumText/TitilliumText22L-Bold.otf"/>

<EditText
android:id="@+id/login_code_et04"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="_"
android:textColorHint="@color/text_gray"
android:textSize="@dimen/textsize_32"
android:layout_toRightOf="@id/login_code_et03"
android:inputType="number"
android:maxLength="1"
android:textColor="@color/text_gray"
fontPath="fonts/TitilliumText/TitilliumText22L-Bold.otf"/>

<EditText
android:id="@+id/login_code_et05"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="_"
android:textColorHint="@color/text_gray"
android:textSize="@dimen/textsize_32"
android:layout_toRightOf="@id/login_code_et04"
android:inputType="number"
android:maxLength="1"
android:textColor="@color/text_gray"
fontPath="fonts/TitilliumText/TitilliumText22L-Bold.otf"/>

<EditText
android:id="@+id/login_code_et06"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="_"
android:textColorHint="@color/text_gray"
android:textSize="@dimen/textsize_32"
android:layout_toRightOf="@id/login_code_et05"
android:inputType="number"
android:maxLength="1"
android:textColor="@color/text_gray"
fontPath="fonts/TitilliumText/TitilliumText22L-Bold.otf"/>

</LinearLayout>
like image 726
Jachumbelechao Unto Mantekilla Avatar asked Sep 04 '15 14:09

Jachumbelechao Unto Mantekilla


2 Answers

Finaly, I found the solution only adding a TextWacher to the EditText and deletin one '' to the next char when adding characters and adding a '' when deleting to de position.

This is the xml code of the EditText:

<EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/editText"
        android:singleLine="true"
        android:text="______"
        android:letterSpacing="0.2"
        android:textSize="29sp" />

And this is the code in the activity:

    EditText editText;
    private String text;
    private boolean delete = false;
    private static final int CODE_SIZE=6;


  private void initTextView() {
        text = editText.getText().toString();

        editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                text = editText.getText().toString();
                if (count > after)
                    delete = true;

            }

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


                StringBuilder sb = new StringBuilder(s.toString());
                int replacePosition = editText.getSelectionEnd();

                if (s.length() != CODE_SIZE) {
                    if (!delete) {
                        if (replacePosition < s.length())
                            sb.deleteCharAt(replacePosition);
                    } else {
                        sb.insert(replacePosition, '_');
                    }

                        if (replacePosition < s.length() || delete) {
                            editText.setText(sb.toString());
                            editText.setSelection(replacePosition);
                        } else {
                            editText.setText(text);
                            editText.setSelection(replacePosition - 1);
                        }
                    }


                }

                delete = false;

            }

            @Override
            public void afterTextChanged(Editable s) {
            }
        });


    }

This code works well in api level 21 and higher, because letterSpacin only work in API level 21 and higher. But if you use a different typography than Android stock it probably works. For me works with TitilliumText22L-Regular.

like image 51
Jachumbelechao Unto Mantekilla Avatar answered Sep 24 '22 06:09

Jachumbelechao Unto Mantekilla


I would try using a TextView behind the EditText (assuming your EditText has a transparent background) to show the underlines and update it whenever the text changes in the EditText.

Otherwise you could subclass EditText and implement some custom drawing in onDraw().

Either of those I think would be better than having 6 EditTexts and managing their focus with all that plumbing.

like image 28
Karakuri Avatar answered Sep 22 '22 06:09

Karakuri