如何检测用户是否在EditText android中停止输入

Pri*_*one 14 android android-edittext

我的布局中有一个EditText字段.我想在用户停止输入该edittext字段时执行操作.我已经实现了TextWatcher并使用了它的功能

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }


@Override
public void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { } 

@Override
    public void afterTextChanged(Editable editable) {

    }
Run Code Online (Sandbox Code Playgroud)

功能onTextChangedafterTextChanged得到的只是输入任何字符后调用,但我希望用户在该领域的EditText完成键入后,就像Facebook并在它的"入住"页面进行操作.

我该如何实现呢?

The*_*izo 34

这就是我为我工作的方式!

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
            // ............
            // ............
            DoStaff();
        }
    }
};

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 {

        }
    }
}

);
Run Code Online (Sandbox Code Playgroud)

  • 这是什么逻辑(last_text_edit + delay-500)。为什么需要500? (3认同)

Rah*_*ury 13

使用RxBindingsAndroid 有一种非常简单易用的方法,

如果你还没有,请到图书馆

compile 'com.jakewharton.rxbinding:rxbinding:0.4.0'
Run Code Online (Sandbox Code Playgroud)

根据您的需要添加和修改此代码段,

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

什么是去抖操作员?- 在此处了解更多信息

在我们的上下文中,debounce只会在内部EditText发生的最后一次文本更改过去一段时间之后通知您内部的文本更改EditText.

在这里,我等待3秒钟,直到最后一次文本更改结束用户已停止输入.您可以根据需要进行修改.


Hug*_*hzi 7

您可以使用焦点更改侦听器.如果edittext具有焦点,则假定用户仍在编辑,否则他们已停止并且您可以执行操作:

    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
            }
        }
    });
Run Code Online (Sandbox Code Playgroud)


Emm*_*her 6

如果您使用Kotlin,请使用以下扩展功能:

fun TextView.afterTextChangedDelayed(afterTextChanged: (String) -> Unit) {
    this.addTextChangedListener(object : TextWatcher {
        var timer: CountDownTimer? = null

        override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}

        override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}

        override fun afterTextChanged(editable: Editable?) {
            timer?.cancel()
            timer = object : CountDownTimer(1000, 1500) {
                override fun onTick(millisUntilFinished: Long) {}
                override fun onFinish() { 
                    afterTextChanged.invoke(editable.toString()) 
                }
            }.start()
        }
    })
}
Run Code Online (Sandbox Code Playgroud)

使用示例:

editTextPassword.afterTextChangedDelayed {
    registerViewModel.addUserPassword(it)
}
Run Code Online (Sandbox Code Playgroud)


Ank*_*wal 5

这是一种有点不同的方法。但是你可以做这样的事情

我假设在用户开始输入 edittext 之后,并且他在特定时间段内没有输入,可以认为他停止输入。

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
            );
        }
    });
Run Code Online (Sandbox Code Playgroud)

基本上,您在这里所做的是,每当用户开始输入时,如果在更改 edittext 内的文本时存在 5000 毫秒的时间间隔,您就认为用户已停止输入。当然,您可以将时间更改为您想要的任何时间

  • FocusChangeListener 是一个糟糕的方法。打字后谁把焦点移开?我在产品上实施了焦点解决方案,但没有人点击来删除焦点。我们必须实现计时器。 (2认同)

小智 5

您可以使用此扩展功能来获取用户停止写入后输入的文本。

例子:

myEditText.doAfterTextChanged{ text ->
// Do your work here
}
Run Code Online (Sandbox Code Playgroud)

默认时间设置为 500 毫秒,因此文本更改回调将在用户停止写入后 500 毫秒后调用。您可以更改默认时间作为函数的参数。

例子:

myEditText.doAfterTextChanged(delay = 1000){ text ->
// Do your work here
}
Run Code Online (Sandbox Code Playgroud)

因此,监听器将在用户停止写入后 1 秒后被调用。

要点链接:https://gist.github.com/rommansabbir/c56cb28e84bdc499cfd7c63180fb9f95