TextWatcher afterTextChanged() 的 Editable.replace() 没有正确替换 EditText 中的文本

TextWatcher afterTextChanged()'s Editable.replace() does not replace text in EditText properly

在 Android 应用程序中,我有一个 EditText 应该用应用程序数据中的值替换某些字符串。

例如如果用户键入 $username,它应该被替换为当前登录的任何用户的名称。

TextWatcherafterTextChanged() 方法中的 Editable 参数应用于 EditText$username 替换为正确的值,但问题是在 $username 被替换为实际的用户名,如果我按下任何字符,它会附加 username 后跟按下的字符。

例如

假设当前登录的用户名是Joe

一个。如果输入是 Hi this is @username

b。 afterTextChanged() 将其更改为 Hi this is Joe

c。现在,如果我按任何其他字符(比如我按 g 或 space),则 EditText 中的文本会更改为 Hi this is JoeusernamegHi this is Joeusername

如何获得步骤 b 中的输出?

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

        }

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

        }

        @Override
        public void afterTextChanged(Editable s) {
            final String strUserNameCode = "$username";
            String text = s.toString();
            if(text.contains(strUserNameCode)){
                int startIndex = text.indexOf(strUserNameCode);
                int endIndex = startIndex + strUserNameCode.length();
                Editable profileName = new SpannableStringBuilder(FileUtil.getUTF8String(settingDTO.getProfileName()));
                s.replace(startIndex, endIndex, profileName);
            }

        }
    });

在您的 afterTextChange 方法中,您应该将文本设置为编辑文本。并且 String 有 replace(CharSequence old, CharSequence new) 方法你也可以使用它。 像这样,

PublishSubject publishSubject = PublishSubject.create();
        publishSubject.debounce(200, TimeUnit.MILLISECONDS)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(query -> onTextChanged(query.toString()));


void onTextChanged(String text){
 final String strUserNameCode = "$username";
     etTemplateMessage.setText(text.replace(strUserNameCode, FileUtil.getUTF8String(settingDTO.getProfileName())));
}

并在您的 aftertextChange 方法调用中 publishSubject.onNext( s.toString())

  • 请注意,您可以使用 RxJava 实现此目的。