TextWatcher - 光标返回到EditText的开头

4

我有以下的TextWatcher定义:

   _textWatcher = 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(final Editable s) {
            if (!s.toString().equals(_prev)) {
                afterTextHandler.removeCallbacks(work);
                work = new Runnable() {
                    @Override
                    public void run() {                            
                        if (!s.toString().equals(_prevQuoteAmount)) {
                            _prev = s.toString();
                            doSomething();
                        }
                        _et.append("");                            
                    }
                };
                afterTextHandler.postDelayed(work, 1000);
            }
            _et.append("");                
        }
    };

一切都按预期工作(有时doSomething()会执行,有时不会执行,所以它的执行与问题无关),但是当用户在具有此监视器的EditText组件中键入一些文本后,文本的光标会回到EditText的开头。
我得到了以下日志,在onTextChanged()执行后(或其处理程序run()执行后)显示:
12-08 13:10:55.777 1855-1855/com.android.inputmethod.latin I/LatinIME: Starting input. Cursor position = 4,4
为什么在onTextChanged()执行后EditText的光标会放置在EditText的开头?
编辑1: _et.append("")是一个hack,应该将光标带到文本的最后一个位置。 它在这里不起作用(尽管在其他情况下它有效)。
编辑2: 有关doSomething的请求知识:
    if (isReady()) {
        Sender objSender = new Sender();
        objSender.setParam1(_tvParam1.getText().toString());
        objSender.setParam2(_tvParam2.getText().toString());
        objSender.setParam3(_et.getText().toString());
        Service.startActionSend(getActivity(), quote);
    }

isReady() - 在发起网络请求之前检查条件(_tvParam1,_tvParam2,_et)。 Service.startActionSend() - 使用IntentService进行异步网络请求。

编辑3: 问题仅在进入处理程序的run()方法时发生。

4个回答

3
您可以使用此函数获取在EditText的setSelection中使用的光标。
private fun getNewCursorPosition(digitCountToRightOfCursor : Int, numberString : String) : Int{
    var position = 0
    var c = digitCountToRightOfCursor
    for (i in numberString.reversed()) {
        if (c == 0)
            break

        if (i.isDigit())
            c --
        position ++


    }
    return numberString.length - position
}

使用整个样本

editText.addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(p0: Editable?) {
        }

        override fun beforeTextChanged(p0: CharSequence?, start: Int, count: Int, after: Int) {
            beforeText = p0.toString()
        }

        override fun onTextChanged(p0: CharSequence?, start: Int, before: Int, count: Int) {
            
            if (p0 == null)
                return
            // 1. get cursor position : p0 = start + before
            val initialCursorPosition = start + before
            //2. get digit count after cursor position : c0
            val numOfDigitsToRightOfCursor = getNumberOfDigits(beforeText.substring(initialCursorPosition,
                    beforeText.length))
            val newAmount = formatAmount(p0.toString())
            editText.removeTextChangedListener(this)
            editText.setText(newAmount)
            //set new cursor position
            editText.setSelection(getNewCursorPosition(numOfDigitsToRightOfCursor, newAmount))
            editText.addTextChangedListener(this)



        }

    })

您可能需要这个函数。

 private fun getNumberOfDigits(@NonNull text : String) : Int{
    var count = 0
    for (i in text)
        if (i.isDigit())
            count++
    return count
}

参考:


2

我不确定你在doSomething()函数里面做了什么,但如果它改变了光标的位置,你可以使用以下的(hack)将光标移动到输入文本的末尾。

mEdittext.setSelection(mEdittext.length());


我已经编辑了一些关于我已经在问题的代码示例中使用的黑客信息。我也尝试过你的方法,但它无法正常工作。 此外,有时会执行doSomething(),有时不会,这意味着它不会影响结果。 - lionheart
我能看一下你的doSomething()函数吗?我很好奇里面发生了什么。 - Swayam
我已经编辑了问题并提供了有关doSomething()的更多信息。谢谢。 - lionheart

0
尝试使用布尔变量来检查状态。
desc.addTextChangedListener(new TextWatcher() {
        boolean changed = false;
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void afterTextChanged(Editable editable) {
            if (desc.getText().toString().isEmpty()) {

                changed = false;
            } else {
                if(!changed) {
                    doSomething();
                }
                changed = true;
            }
        }
    });

0
 <EditText
    android:id="@+id/user_input_first_name"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:maxLines="1"
    android:textAllCaps="true"
    android:textColor="@color/black"
    android:textSize="20sp"
    android:textStyle="bold" />

对我来说,当我移除了textAllCaps、focusable和focusableInTouchMode时,问题得到了解决。


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