【问题标题】:Live editing of users input实时编辑用户输入
【发布时间】:2011-05-09 12:07:22
【问题描述】:

是否可以在用户输入数据时自动将字符插入EditText

即如果用户正在输入一个长数字,例如123456789012,这个数字是否可以在他在编辑文本框中输入时出现,但每隔 4 个字符有一个破折号?

因此,当您键入上面的数字时,您会看到它被输入到 EditText 框中,但看起来像这样:1234-5678-9012。

目前我有一个应用程序,您可以在其中输入一个长数字,然后按一个按钮,它会为您插入破折号,但我很好奇是否可以在您键入时完成?

非常感谢您的帮助。

【问题讨论】:

  • 什么语言?什么平台?一般来说,这是可能的,但细节取决于语言和平台。
  • 采用什么技术?例如。在网页、iPhone 应用等中。

标签: android string android-edittext


【解决方案1】:

通过标记android,我认为您正在讨论android editText,因此您可以通过监听TextChangedListener 来做到这一点,

已编辑:用于退格

editText.addTextChangedListener(new TextWatcher() {
            int len=0;
            @Override
            public void afterTextChanged(Editable s) { 
                String str = editText.getText().toString(); 
                 if(str.length()==4&& len <str.length()){//len check for backspace 
                    editText.append("-");
                }
            }

            @Override
            public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {

             String str = editText.getText().toString(); 
              len = str.length();
            }

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


        }); 

【讨论】:

  • 太棒了。非常感谢您的回答。
  • 也要处理删除 - 给出的示例可能会在输入 4 个字符后无法退格(因为删除破折号会立即添加另一个字符)。
  • @Nick ,我已经为退格编辑了它,所以它不是不可能的
  • @LabeebP 我已经尝试使用它。但如果我按退格键。 - 也不会删除。同样,一旦编辑文本中的破折号预览,光标将被移入向前
  • 这不会在我的编辑文本中添加破折号。可能是什么原因?
【解决方案2】:

为了解决这个问题,我编写了一个“AutoAddTextWatcher”类:

1. 自动将文本插入 EditText。
2. 在您设置的位置将文本插入 EditText。
3.当文本长度大于1时,删除EditText中你设置的位置的文本。

代码 sn-p:

mEditText_birthday.addTextChangedListener(new AutoAddTextWatcher(mEditText_birthday,
            "/",
            new TextWatcher() {},
            4, 6));

AutoAddTextWatcher 类

import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;


/**
 * Created by henry.chuang on 2016/5/12.
 */
public class AutoAddTextWatcher implements TextWatcher {
    private CharSequence mBeforeTextChanged;
    private TextWatcher mTextWatcher;
    private int[] mArray_pos;
    private EditText mEditText;
    private String mAppentText;

    public AutoAddTextWatcher(EditText editText, String appendText, int... position){
        this.mEditText = editText;
        this.mAppentText = appendText;
        this.mArray_pos = position.clone();
    }
    public AutoAddTextWatcher(EditText editText, String appendText, TextWatcher textWatcher, int... position){
        this(editText, appendText, position);
        this.mTextWatcher = textWatcher;
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        mBeforeTextChanged = s.toString();

        if(mTextWatcher != null)
            mTextWatcher.beforeTextChanged(s, start, count, after);

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        for (int i = 0; i < mArray_pos.length; i++) {
            if(((mBeforeTextChanged.length() - mAppentText.length() * i) == (mArray_pos[i] - 1) &&
                    (s.length() - mAppentText.length() * i) == mArray_pos[i])){
                mEditText.append(mAppentText);

                break;
            }

            if(((mBeforeTextChanged.length() - mAppentText.length() * i) == mArray_pos[i] &&
                    (s.length() - mAppentText.length() * i) == (mArray_pos[i] + 1))){
                int idx_start = mArray_pos[i] + mAppentText.length() * i;
                int idx_end = Math.min(idx_start + mAppentText.length(), s.length());

                String sub = mEditText.getText().toString().substring(idx_start,  idx_end);

                if(!sub.equals(mAppentText)){
                    mEditText.getText().insert(s.length() - 1, mAppentText);
                }

                break;
            }

            if(mAppentText.length() > 1 &&
                    (mBeforeTextChanged.length() - mAppentText.length() * i) == (mArray_pos[i] + mAppentText.length()) &&
                    (s.length() - mAppentText.length() * i) == (mArray_pos[i] + mAppentText.length() - 1)){
                int idx_start = mArray_pos[i] + mAppentText.length() * i;
                int idx_end = Math.min(idx_start + mAppentText.length(), s.length());

                mEditText.getText().delete(idx_start, idx_end);

                break;
            }

        }

        if(mTextWatcher != null)
            mTextWatcher.onTextChanged(s, start, before, count);

    }

    @Override
    public void afterTextChanged(Editable s) {
        if(mTextWatcher != null)
            mTextWatcher.afterTextChanged(s);

    }

}

完整的演示源:
https://github.com/henrychuangtw/AutoInsertEditText

【讨论】:

  • 哇老兄!你是个天才!非常感谢您...我尝试了很多解决方案,但没有任何效果。我需要将其格式化为:12-345-67。当您删除然后尝试重新输入时,所有其他解决方案总是会发生奇怪的事情。您的解决方案非常有效!不过需要注意的一件事是,为了让您的课程正常工作,您需要将 XML 文件中的输入类型设置为 android:inputType="phone" 我最初尝试使用 android:inputType="number" 但它不起作用。我检查了你的 github 页面,发现你使用了phone,现在可以了。干得好!
  • 这是我的实现:enterUserID.addTextChangedListener(new AutoAddTextWatcher(enterUserID, "-", 2, 5));
  • @KevinBright 谢谢你的鼓励和建议,我会试试的。
  • 不,谢谢!我无法相信在 Android 中正确地做到这一点有多难!
  • @HenryChuang:你的代码很棒。以前我通过很多努力实现了自己的方式。但是您的代码肯定会帮助人们。如果我想为您的代码实现复制粘贴侦听器,我们该如何实现。
【解决方案3】:
@Override
public void afterTextChanged(Editable s) {

    if(s.length() == 3 && len < s.length()){
        s.append(" - ");
    }

}

@Override
public void beforeTextChanged(CharSequence s, int start, int count,
        int after) {
    len = s.length();
}

这也可以,只有这段代码会在第三个字符之后插入" - "

【讨论】:

    【解决方案4】:

    这是我用的

    private boolean mInEdit;
    
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if (!mInEdit) {
            mInEdit = true;
            String delimiter = " - ";
            //Remove chars from your delimiter first
            String digits = s.toString().replaceAll("[- ]", "")
                    .replaceAll("\\d{4}", "$0" + delimiter);
            //Handle deletion
            int dLength = delimiter.length();
            if (before > count && digits.endsWith(delimiter.charAt(dLength - 1)) {
                digits = digits.substring(0, digits.length() - dLength);
            }
            mCardNumber.setText(digits);
            mCardNumber.setSelection(mCardNumber.length());
            mInEdit = false;
        }
    }
    

    在这里,您将分隔符替换为要分隔数字的内容。

    【讨论】:

      【解决方案5】:

      对于那些仍然面临退格和多个连字符问题的人 -

      new TextWatcher() 
      {
              boolean hyphenExists;
      
              @Override
              public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                  if (s.length() >= 6 && s.charAt(5) == '-') {
                      hyphenExists = true;
                  } else {
                      hyphenExists = false;
                  }
      
                  Log.d("TAG", "beforeTextChanged " + s.toString());
              }
      
              @Override
              public void onTextChanged(CharSequence s, int start, int before, int count) {
      
                  Log.d("TAG", "onTextChanged " + s.toString());
              }
      
              @Override
              public void afterTextChanged(Editable s) {
                  if (s.length() == 5) {
                      if (!hyphenExists)
                          s.append('-');
                  }
                  Log.d("TAG", "afterTextChanged " + s.toString());
              }
          }
      

      【讨论】:

        【解决方案6】:

        您可以通过更改文本来实现此目的

        就我而言,我必须像这样格式化输入:xxx xxx-xxxx

        我按以下方式完成:

        etMobileNumber.addTextChangedListener(object : TextWatcher {
                override fun afterTextChanged(s: Editable?) {
        
        
                }
        
                override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
                }
        
                override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                    if (etMobileNumber.text.length == 3 && count != 0) {
                        val text = etMobileNumber.getText().toString() + " "
                        etMobileNumber.setText(text)
                        etMobileNumber.setSelection(text.length)
                    } else if (etMobileNumber.text.length == 7 && count != 0) {
                        val text = etMobileNumber.getText().toString() + "-"
                        etMobileNumber.setText(text)
                        etMobileNumber.setSelection(text.length)
                    }
                }
            })
        

        而且打字时结果非常动态。

        输入- 1234567890 结果 - 123 456-7890

        【讨论】:

          猜你喜欢
          • 2022-12-04
          • 1970-01-01
          • 1970-01-01
          • 2011-01-18
          • 1970-01-01
          • 2022-07-22
          • 1970-01-01
          • 2014-06-05
          相关资源
          最近更新 更多