简体   繁体   English

Android:有没有办法确定在edittext软键盘上按键/按下键的时间?

[英]Android: Is there any way to identify when the keys are pressed/unpressed on an edittext softkeyboard?

I have an autocomplete edittext field that sends queries to a server everytime the text changes, however if the user types a lot of text and then holds down "delete" I don't want to send a query for every single character deleted. 我有一个自动完成的edittext字段,每次文本更改时都会向服务器发送查询,但是如果用户输入大量文本然后按住“删除”,我不想为删除的每个字符发送查询。 One way of getting around this would be to cache all the queries as the characters were entered and then play back the cache on deletion - but that seems to me to be unnecessarily complicated. 解决这个问题的一种方法是在输入字符时缓存所有查询,然后在删除时回放缓存 - 但在我看来这似乎是不必要的复杂。 An easier way is to detect keydown/keyup and then only send a query if the text has changed but the user also isn't touching the keyboard. 一种更简单的方法是检测keydown / keyup,然后仅在文本已更改但用户也未触摸键盘时才发送查询。 Which leads me to the difficulty of how to catch keyup from a softkeyboard. 这让我很难知道如何从软键盘中获取键盘。

I've already tried ontouchlistener (doesn't fire) and onkeypressedlistener (also doesnt fire) and even overriding onKeyPreIme inside the edittext (also doesn't fire). 我已经尝试过ontouchlistener(不会触发)和onkeypressedlistener(也不会触发)甚至覆盖edittext中的onKeyPreIme(也不会触发)。 Is there a way of doing this? 有办法做到这一点吗?

The way I fixed this problem is to add a delay to the query so it won't execute every time. 解决此问题的方法是向查询添加延迟,以便每次都不执行。 My code looked something like this: 我的代码看起来像这样:

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
    }
}

Hope this helps. 希望这可以帮助。

You can't detect it directly, but you could find an indirect way by overriding the onMeasure in your Activity and detecting when it shrinks and expand over a certain threshold, as long as you define in your Manifest android:windowSoftInputMode to be adjustResize . 您无法直接检测到它,但是您可以通过覆盖Activity中的onMeasure并检测它何时收缩并扩展超过某个阈值来找到间接方式,只要您在Manifest中定义android:windowSoftInputModeadjustResize

In my experience, though, the method is not extremely reliable. 但根据我的经验,这种方法并不是非常可靠。 You should also consider that the user may leave your activity without closing the keyboard. 您还应该考虑用户可以在不关闭键盘的情况下离开您的活动。

It depends on what kind of action you need to take upon deletion, but I was in a similar case where I needed to save the edited text to a shared preference. 这取决于您在删除时需要采取的操作类型,但我遇到了类似情况,我需要将编辑后的文本保存到共享首选项。 I found that the best solution is to save it at every character deletion: it's the only safe and consistent method I've found and the performance hit is not noticeable. 我发现最好的解决方案是在每次删除字符时保存它:它是我发现的唯一安全且一致的方法,并且性能损失不明显。

Better use TextWatcher 更好地使用TextWatcher

1)Create one TextWatcher listener object : 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)Register this listener to your edittext 2)将此监听器注册到您的edittext

myEditText.addTextChangedListener(myTextWatcher);

If you only want to identify the delete key pressed in the softkeyboard then try this.. 如果您只想识别在键盘中按下的删除键,那么试试这个..

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; 
    } 
}); 

My final solution was to combine Andrea's answer with Jelle's. 我的最终解决方案是将Andrea的答案与Jelle的答案结合起来。 I record the last time a key was pressed in a textwatcher and only test against it 500 ms after that - in order to know for sure that it was the last key pressed: 我记录了上次在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 ...

        }
    });

then I put in this method: 然后我把这个方法:

private void checkIfTimeHasPassed() {
        if (!TextUtils.isEmpty(stringToSearchFor) && edittext.getText().length() > 2 && System.currentTimeMillis() - lastCharacterPress > 499) {
                // perform the actual query
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM