我有一个表单,用户可以在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);
导致整个Watcher以递归方式运行。我可以通过添加txtEmail.setSelection(temp.length());
来控制插入位置以转到EditText的末尾,并使用if
转义递归循环,但是我找不到一种方法来保持我的插入符号在特定点。例如,如果我写了&#34; myema(il missing)@ something.com,并希望返回对每个输入的字母进行修正,则插入符号位于字符串的末尾。
现在奇怪的部分。我尝试在beforeTextChanged(...)
或onTextChanged(...)
之前保留插入符号的位置。在我输入内容的那一刻,插入位置在每种情况下都被正确改变。然而,那一刻,我们进入递归调用,插入符号的位置报告为0.我猜测当我实际键入时,插入符号移动也被注册,但因为在递归调用中没有插入符号移动而不是&# 34;粘贴&#34;在EditText中我没有得到任何位置变化。
因此问题是:我如何保持插入符号的位置?我的想法是实际上字符串文本。获取插入符号的所有内容,然后使用txtEmail.setSelection(temp.length());
将更改添加到其中,然后在else步骤中附加其余字符串(尚未尝试)。有没有其他(更简单/更有效)的方法,我可以使用内置工具处理它?</ p>
提前致谢!
答案 0 :(得分:1)
也许你已经采取了艰难的方式。为什么不使用
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();
}
}
});