Android:有什么方法可以识别 edittext 软键盘上的键何时为 pressed/unpressed?
Android: Is there any way to identify when the keys are pressed/unpressed on an edittext softkeyboard?
我有一个自动完成的 edittext 字段,每次文本更改时都会向服务器发送查询,但是如果用户键入大量文本然后按住 "delete" 我不想发送查询每个字符都删除了。解决这个问题的一种方法是在输入字符时缓存所有查询,然后在删除时回放缓存 - 但在我看来这太复杂了。一种更简单的方法是检测 keydown/keyup ,然后仅在文本已更改但用户也没有触摸键盘时才发送查询。这让我遇到了如何从软键盘捕捉键盘的困难。
我已经尝试过 ontouchlistener(不触发)和 onkeypressedlistener(也不触发),甚至在 edittext 中覆盖 onKeyPreIme(也不触发)。有办法吗?
我解决这个问题的方法是为查询添加延迟,这样它就不会每次都执行。我的代码看起来像这样:
long lastPress = 0l;
@Override
public void onTextChanged(CharSequence s,
int start, int before, int count){
if(System.currentTimeMillis() - lastpress > 500){
lastPress= System.currentTimeMillis();
// insert query here
}
}
希望对您有所帮助。
您无法直接检测到它,但您可以通过覆盖 Activity 中的 onMeasure 并检测它何时收缩和扩展超过某个阈值来找到间接方法,只要您在将 android:windowSoftInputMode
显示为 adjustResize
。
不过,根据我的经验,该方法并不是非常可靠。您还应该考虑到用户可能会在不关闭键盘的情况下离开您的 activity。
这取决于您在删除时需要采取什么样的操作,但我遇到过类似的情况,我需要将编辑后的文本保存到共享首选项中。我发现最好的解决方案是在每次删除字符时保存它:这是我发现的唯一安全且一致的方法,而且性能影响并不明显。
更好用TextWatcher
1)创建一个TextWatcher
监听器对象:
private static long time = 0;
private final long TIME_DELAY = 700;
private final TextWatcher myTextWatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
public void afterTextChanged(Editable s) {
if(System.currentTimeMillis() - time > TIME_DELAY ){
time= System.currentTimeMillis();
// your codes
}
}
};
2)将此侦听器注册到您的 edittext
myEditText.addTextChangedListener(myTextWatcher);
如果您只想识别在软键盘中按下的删除键,那么试试这个..
final EditText edit1 = (EditText) findViewById(R.id.editText1);
edit1.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
// You can identify which key pressed buy checking keyCode value
// with KeyEvent.KEYCODE_
if (keyCode == KeyEvent.KEYCODE_DEL) {
// this is for backspace
Log.e("IME_TEST", "DEL KEY");
}
return false;
}
});
我的最终解决方案是将 Andrea 的回答与 Jelle 的回答结合起来。我记录了最后一次在 textwatcher 中按下一个键,然后仅在 500 毫秒之后对其进行测试 - 为了确定它是最后按下的键:
private static long lastCharacterPress = 0l;
private Editable stringToSearchFor;
private Handler delayedCharacterCheck;
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) {
}
@Override
public void afterTextChanged(Editable s) {
lastCharacterPress = System.currentTimeMillis();
stringToSearchFor = s;
if (s.length() > 2) {
delayedCharacterCheck.postDelayed(new Runnable() {
@Override
public void run() {
checkIfTimeHasPassed();
}
}, 500);
} else ...
}
});
然后我输入这个方法:
private void checkIfTimeHasPassed() {
if (!TextUtils.isEmpty(stringToSearchFor) && edittext.getText().length() > 2 && System.currentTimeMillis() - lastCharacterPress > 499) {
// perform the actual query
}
}
我有一个自动完成的 edittext 字段,每次文本更改时都会向服务器发送查询,但是如果用户键入大量文本然后按住 "delete" 我不想发送查询每个字符都删除了。解决这个问题的一种方法是在输入字符时缓存所有查询,然后在删除时回放缓存 - 但在我看来这太复杂了。一种更简单的方法是检测 keydown/keyup ,然后仅在文本已更改但用户也没有触摸键盘时才发送查询。这让我遇到了如何从软键盘捕捉键盘的困难。
我已经尝试过 ontouchlistener(不触发)和 onkeypressedlistener(也不触发),甚至在 edittext 中覆盖 onKeyPreIme(也不触发)。有办法吗?
我解决这个问题的方法是为查询添加延迟,这样它就不会每次都执行。我的代码看起来像这样:
long lastPress = 0l;
@Override
public void onTextChanged(CharSequence s,
int start, int before, int count){
if(System.currentTimeMillis() - lastpress > 500){
lastPress= System.currentTimeMillis();
// insert query here
}
}
希望对您有所帮助。
您无法直接检测到它,但您可以通过覆盖 Activity 中的 onMeasure 并检测它何时收缩和扩展超过某个阈值来找到间接方法,只要您在将 android:windowSoftInputMode
显示为 adjustResize
。
不过,根据我的经验,该方法并不是非常可靠。您还应该考虑到用户可能会在不关闭键盘的情况下离开您的 activity。
这取决于您在删除时需要采取什么样的操作,但我遇到过类似的情况,我需要将编辑后的文本保存到共享首选项中。我发现最好的解决方案是在每次删除字符时保存它:这是我发现的唯一安全且一致的方法,而且性能影响并不明显。
更好用TextWatcher
1)创建一个TextWatcher
监听器对象:
private static long time = 0;
private final long TIME_DELAY = 700;
private final TextWatcher myTextWatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
public void afterTextChanged(Editable s) {
if(System.currentTimeMillis() - time > TIME_DELAY ){
time= System.currentTimeMillis();
// your codes
}
}
};
2)将此侦听器注册到您的 edittext
myEditText.addTextChangedListener(myTextWatcher);
如果您只想识别在软键盘中按下的删除键,那么试试这个..
final EditText edit1 = (EditText) findViewById(R.id.editText1);
edit1.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
// You can identify which key pressed buy checking keyCode value
// with KeyEvent.KEYCODE_
if (keyCode == KeyEvent.KEYCODE_DEL) {
// this is for backspace
Log.e("IME_TEST", "DEL KEY");
}
return false;
}
});
我的最终解决方案是将 Andrea 的回答与 Jelle 的回答结合起来。我记录了最后一次在 textwatcher 中按下一个键,然后仅在 500 毫秒之后对其进行测试 - 为了确定它是最后按下的键:
private static long lastCharacterPress = 0l;
private Editable stringToSearchFor;
private Handler delayedCharacterCheck;
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) {
}
@Override
public void afterTextChanged(Editable s) {
lastCharacterPress = System.currentTimeMillis();
stringToSearchFor = s;
if (s.length() > 2) {
delayedCharacterCheck.postDelayed(new Runnable() {
@Override
public void run() {
checkIfTimeHasPassed();
}
}, 500);
} else ...
}
});
然后我输入这个方法:
private void checkIfTimeHasPassed() {
if (!TextUtils.isEmpty(stringToSearchFor) && edittext.getText().length() > 2 && System.currentTimeMillis() - lastCharacterPress > 499) {
// perform the actual query
}
}