0

我有一个表单,用户可以在其中输入一些数据 EditText 字段。其中一个 EditText 小部件用于电子邮件地址。我正在使用 TextWatcher 来确保文本始终为小写,如下所示:

txtEmail.addTextChangedListener(new TextWatcher()
    {
        String prevString = "";
        boolean delAction = false;

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after)
        {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count)
        {
            if (s.length() < prevString.length())
                delAction = true;
            else
                delAction = false;
        }

        @Override
        public void afterTextChanged(Editable s)
        {
            if (!delAction)
            {
                String temp = s.toString().toLowerCase();
                if (!temp.equals(prevString))
                {
                    prevString = temp;
                    txtEmail.setText(temp); // Recursive
                    txtEmail.setSelection(temp.length());
                }
            }
            else
            {
                prevString = s.toString();
            }
        }
    });

onTextChanged(...)我还进行比较以确保删除工作正常。

现在来解决问题。txtEmail.setText(temp);导致整个观察者递归运行。txtEmail.setSelection(temp.length());我可以通过添加和转义递归循环来控制插入符号位置到 EditText 的末尾,if但是我找不到将插入符号保持在特定点的方法。例如,如果我写了“myema(il missing)@something.com”并想在输入的每个字母处返回以进行更正,则插入符号位于字符串的末尾。

现在奇怪的部分。我尝试将插入符号的位置保持在beforeTextChanged(...)or之前onTextChanged(...)。在我输入某些内容的那一刻,插入符号的位置在每种情况下都会正确更改。但是,当我们进入递归调用时,插入符号的位置报告为 0。我猜当我实际键入时,插入符号的移动也被注册了,但是因为在递归调用中没有插入符号移动而不是“粘贴” " EditText 中的文本我没有得到位置变化。

因此问题是:我怎样才能保持插入符号的位置?我的想法是实际上对文本进行子串化。将所有内容都放到插入符号中,使更改与 the 一起扔到那里,txtEmail.setSelection(temp.length());然后在 else 步骤中附加字符串的其余部分(目前尚未尝试)。有没有其他(更简单/有效)的方法可以使用内置工具来处理?

提前致谢!

4

1 回答 1

2

也许你已经很难做到这一点。为什么不使用

android:digits="qwertyuiopasdfghjklzxcvbnm_,.@.," 

用于电子邮件的 EditText?如果您允许用户输入任何其他字符,只需将它们添加到android:digits字段。

由 OP 编辑​​:

在遵循 Alexandru 的建议(请参阅评论)取消注册并再次注册 TextWatcher 之后,代码更改并按如下方式工作:

    txtEmail.addTextChangedListener(new TextWatcher()
    {
        String prevString = "";
        boolean delAction = false;
        int caretPos = 0;

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after)
        {
            caretPos = txtEmail.getSelectionStart();
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count)
        {
            if (s.length() < prevString.length())
                delAction = true;
            else
                delAction = false;
        }

        @Override
        public void afterTextChanged(Editable s)
        {
            if (!delAction)
            {
                prevString = s.toString().toLowerCase();
                txtEmail.removeTextChangedListener(this);
                txtEmail.setText(prevString);
                txtEmail.addTextChangedListener(this);
                txtEmail.setSelection(caretPos + 1);
            }
            else
            {
                txtEmail.setSelection(caretPos - 1);
                prevString = s.toString();
            }
        }
    });
于 2017-04-20T11:03:26.313 回答