如何在Android中创建一个带有字符下划线的Edittext,用于固定大小的字符串?

7
我需要创建一个EditText,当用户添加新字符时,它将替换下划线。类似于这样:enter image description here 我已经做了类似的东西,使用了6个EditText(所需字符串的大小)和一个'_'字符作为提示。在编辑其中一个EditText时,会将焦点转移到下一个EditText;删除时将焦点转移到前一个EditText,但是当删除或编辑不是最后添加的字符时会出现问题。请问有人知道如何解决吗?以下是我在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();
               }
           }
       });
   }

布局代码如下:

<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>
2个回答

8

最终,我找到了解决方案:只需将TextWatcher添加到EditText中,在添加字符时删除一个'',并在删除字符时添加一个''到指定位置即可。

这是EditText的XML代码:

<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" />

这是活动中的代码:

    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) {
            }
        });


    }

这段代码在API 21及更高版本中有效,因为letterSpacing只能在API 21及更高版本中工作。但如果你使用与Android默认字体不同的字体,则很可能会起作用。对我来说,TitilliumText22L-Regular有效。


1

我建议你在EditText的背后使用一个TextView(假设你的EditText具有透明背景),以显示下划线,并在EditText中的文本更改时更新它。

另外,你也可以继承EditText并在onDraw()方法中实现一些自定义绘制。

我认为以上两种方法都比使用6个EditText并通过各种操作来管理它们的焦点要好。


谢谢。我认为应该是这样的,但如果我在EditText中间删除一个字符,那么该行将出现在EditText的末尾,而不是删除的位置。 - Jachumbelechao Unto Mantekilla
@JachumbelechaoUntoMantekilla 这是必须的吗?我认为作为用户,如果我删除中间的文本,我的期望是其余的文本会自动填充空白。这就是其他所有文本字段的行为方式,那么为什么要与众不同呢? - Karakuri
是的,这是一个要求。如果是我,我会按照你说的去做。 - Jachumbelechao Unto Mantekilla
最终,我找到了一个解决方案。 - Jachumbelechao Unto Mantekilla

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接