How to detect if users stop typing in EditText android

前端 未结 7 1307
长情又很酷
长情又很酷 2020-12-24 14:31

I have an EditText field in my layout. I want to perform an action when the user stops typing in that edittext field. I have implemented TextWatcher and use its functions

相关标签:
7条回答
  • 2020-12-24 15:12

    You could use a focus change listener. If the edittext has focus then assume user still editing otherwise they have stopped and you can perform your action:

        EditText et = new EditText(mContext);
        et.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View view, boolean hasFocus) {
                if (hasFocus) {
                    //user has focused
                } else {
                    //focus has stopped perform your desired action
                }
            }
        });
    
    0 讨论(0)
  • 2020-12-24 15:16

    There is a very simple and easy way of doing this using RxBindings for Android,

    Get the library if you haven't already,

    compile 'com.jakewharton.rxbinding:rxbinding:0.4.0'
    

    Add and modify this snippet to your needs,

    RxTextView.textChanges(mEditText)
                .debounce(3, TimeUnit.SECONDS)
                .subscribe(textChanged -> {
                    Log.d("TAG", "Stopped typing!");
                });
    

    What is Debounce Operator? - Learn more about it here

    In our context, debounce will only notify you of the text change inside the EditText after a certain time has passed from the last text change that occurred inside the EditText.

    Here I am waiting for 3 seconds until the last text change happened to conclude that the user has stopped typing. You can modify it according to your needs.

    0 讨论(0)
  • 2020-12-24 15:16
    import android.os.Handler
    import android.text.Editable
    import android.text.TextWatcher
    
    class EndTypingWatcher(
            var delayMillis: Long = DELAY,
            val action: () -> Unit
    
    ) : Handler(), TextWatcher {
        companion object {
            private const val DELAY: Long = 1000
        }
    
        var lastEditTime: Long = 0
    
        private val finishCheckerRunnable = Runnable {
            if (System.currentTimeMillis() > lastEditTime + delayMillis - 500) {
                action.invoke()
            }
        }
    
        override fun afterTextChanged(s: Editable?) {
            afterTextChanged()
        }
    
        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            onTextChanged()
        }
    
        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
        }
    
        private fun afterTextChanged() {
            lastEditTime = System.currentTimeMillis()
            postDelayed(finishCheckerRunnable, delayMillis)
        }
    
        private fun onTextChanged() {
            removeCallbacks(finishCheckerRunnable)
        }
    
    }
    

    Usage:

    private const val DELAY_AFTER_STOP_TYPING = 2000
    
    ...
    
    editText.addTextChangedListener(EndTypingWatcher(delayMillis = DELAY_AFTER_STOP_TYPING) {
        //Some end action
    })
    
    0 讨论(0)
  • 2020-12-24 15:18

    I used a CountDownTimer to find out if the user stopped typing after a while. I hope to help.

    yourEditText.addTextChangedListener(new TextWatcher() {
    
            CountDownTimer timer = null;
    
            @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 (timer != null) {
                    timer.cancel();
                }
    
                timer = new CountDownTimer(1500, 1000) {
    
                    public void onTick(long millisUntilFinished) {
                    }
    
                    public void onFinish() {
    
                        //do what you wish
    
                    }
    
                }.start();
    
            }
    
            @Override
            public void afterTextChanged(Editable s) {
    
            }
        });
    
    0 讨论(0)
  • 2020-12-24 15:19

    It is a little different kind of approach. But you can do something like this

    I am assuming that after a user started typing in the edittext, and he didn't typed for a particular time period than it can be considered that he stopped typing.

    editText.addTextChangedListener(new TextWatcher() {
    
            boolean isTyping = 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) {}
    
            private Timer timer = new Timer();
            private final long DELAY = 5000; // milliseconds
    
            @Override
            public void afterTextChanged(final Editable s) {
                Log.d("", "");
                if(!isTyping) {
                    Log.d(TAG, "started typing");
                    // Send notification for start typing event
                    isTyping = true;
                }
                timer.cancel();
                timer = new Timer();
                timer.schedule(
                        new TimerTask() {
                            @Override
                            public void run() {
                                isTyping = false;
                                Log.d(TAG, "stopped typing");
                                //send notification for stopped typing event
                            }
                        },
                        DELAY
                );
            }
        });
    

    Basically what you are doing here is, that whenever a user starts typing, if there is a time gap of 5000 milliseconds in changing the text inside the edittext, you consider as the user has stopped typing. Of course you can change the time to whatever you want

    0 讨论(0)
  • 2020-12-24 15:23

    This is how I did and works for me!

    long delay = 1000; // 1 seconds after user stops typing
    long last_text_edit = 0;
    Handler handler = new Handler();
    
    private Runnable input_finish_checker = new Runnable() {
        public void run() {
            if (System.currentTimeMillis() > (last_text_edit + delay - 500)) {
                // TODO: do what you need here
                // ............
                // ............
                DoStuff();
            }
        }
    };
    
    EditText editText = (EditText) findViewById(R.id.editTextStopId);
    editText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged (CharSequence s,int start, int count,
        int after){
        }
        @Override
        public void onTextChanged ( final CharSequence s, int start, int before,
        int count){
            //You need to remove this to run only once
            handler.removeCallbacks(input_finish_checker);
    
        }
        @Override
        public void afterTextChanged ( final Editable s){
            //avoid triggering event when text is empty
            if (s.length() > 0) {
                last_text_edit = System.currentTimeMillis();
                handler.postDelayed(input_finish_checker, delay);
            } else {
    
            }
        }
    }
    
    );
    
    0 讨论(0)
提交回复
热议问题