TextWatcher onTextChanged 不适用于软键盘自动完成/建议词
TextWatcher onTextChanged not working with soft keyboard auto-complete / suggested words
我正在 EditText 上实现 TextWatcher,以便在用户输入新字符时查找文本中的一系列关键字并为其添加下划线。 However when a suggested / auto-complete word on the soft keyboard is selected, instead of adding the suggested word to the Edittext and then calling the onTextChanged function the half complete word is deleted.我发现这很奇怪,因为输入单个字符可以很好地激活 onTextChanged 函数。任何帮助将不胜感激。
PS。如果有人知道更好的动态处理 EditText 的方法,请告诉我。
代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_codify_test);
final EditText editText = (EditText) findViewById(R.id.editText_codifyTest);
editText.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) {
if (!checked) { //stop infinite loop
checked = true;
cursorPosition = editText.getSelectionStart(); //get cursor position before text modification
codifyText(editText);
} else {
checked = false;
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
//Find and underline keywords
private void codifyText(EditText editText) {
String plainText = editText.getText().toString() + " ";
int prevWhiteSpace = 0;
final Context context = this;
SpannableString codifiedText = new SpannableString(plainText.substring(0, plainText.length() - 1));
if (codifiedText.length() == 0) return;
for (int i = 0; i < plainText.length(); i ++){
if (Character.isWhitespace(plainText.charAt(i))){
String currWord = plainText.substring(prevWhiteSpace, i);
if (isKeyWordInDataBase(currWord)) {
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View view) {
}
};
codifiedText.setSpan(clickableSpan, prevWhiteSpace, i, 0);
}
prevWhiteSpace = i + 1;
}
}
editText.setMovementMethod(LinkMovementMethod.getInstance());
editText.setText(codifiedText, TextView.BufferType.SPANNABLE);
editText.setSelection(cursorPosition); //set cursor to position prior to edit
}
最好使用 afterTextChanged 方法。
在以下示例中,使用处理程序检索和处理输入的文本以进行进一步处理
EditText text1;
StringBuffer previousChar=new StringBuffer();
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
text1=(EditText)findViewById(R.id.editText);
text1.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) {
if(!previousChar.toString().equals(s.toString())){
Message msg=new Message();
msg.obj=s.toString();
localHandler.sendMessage(msg);
previousChar=new StringBuffer(s.toString());
Log.i("TAG", "TextEntered = "+s);
}
}
});}
并且在处理程序中
private Handler localHandler = new Handler(){
public void handleMessage(Message msg) {
super.handleMessage(msg);
String value=(String)msg.obj;
//Your logic with the text entered that is retrieved
}
};
我正在 EditText 上实现 TextWatcher,以便在用户输入新字符时查找文本中的一系列关键字并为其添加下划线。 However when a suggested / auto-complete word on the soft keyboard is selected, instead of adding the suggested word to the Edittext and then calling the onTextChanged function the half complete word is deleted.我发现这很奇怪,因为输入单个字符可以很好地激活 onTextChanged 函数。任何帮助将不胜感激。
PS。如果有人知道更好的动态处理 EditText 的方法,请告诉我。
代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_codify_test);
final EditText editText = (EditText) findViewById(R.id.editText_codifyTest);
editText.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) {
if (!checked) { //stop infinite loop
checked = true;
cursorPosition = editText.getSelectionStart(); //get cursor position before text modification
codifyText(editText);
} else {
checked = false;
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
//Find and underline keywords
private void codifyText(EditText editText) {
String plainText = editText.getText().toString() + " ";
int prevWhiteSpace = 0;
final Context context = this;
SpannableString codifiedText = new SpannableString(plainText.substring(0, plainText.length() - 1));
if (codifiedText.length() == 0) return;
for (int i = 0; i < plainText.length(); i ++){
if (Character.isWhitespace(plainText.charAt(i))){
String currWord = plainText.substring(prevWhiteSpace, i);
if (isKeyWordInDataBase(currWord)) {
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View view) {
}
};
codifiedText.setSpan(clickableSpan, prevWhiteSpace, i, 0);
}
prevWhiteSpace = i + 1;
}
}
editText.setMovementMethod(LinkMovementMethod.getInstance());
editText.setText(codifiedText, TextView.BufferType.SPANNABLE);
editText.setSelection(cursorPosition); //set cursor to position prior to edit
}
最好使用 afterTextChanged 方法。
在以下示例中,使用处理程序检索和处理输入的文本以进行进一步处理
EditText text1;
StringBuffer previousChar=new StringBuffer();
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
text1=(EditText)findViewById(R.id.editText);
text1.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) {
if(!previousChar.toString().equals(s.toString())){
Message msg=new Message();
msg.obj=s.toString();
localHandler.sendMessage(msg);
previousChar=new StringBuffer(s.toString());
Log.i("TAG", "TextEntered = "+s);
}
}
});}
并且在处理程序中
private Handler localHandler = new Handler(){
public void handleMessage(Message msg) {
super.handleMessage(msg);
String value=(String)msg.obj;
//Your logic with the text entered that is retrieved
}
};