android EditText - 完成的输入事件

edd*_*yuk 106 android android-edittext

我想在用户完成编辑EditText时捕获一个事件.

怎么做到呢?

Vin*_*tti 176

更好的方法是,您还可以使用EditText onFocusChange监听器来检查用户是否已完成编辑:( 无需依赖用户按下软键盘上的Done或Enter按钮)

 ((EditText)findViewById(R.id.youredittext)).setOnFocusChangeListener(new OnFocusChangeListener() {

    @Override
    public void onFocusChange(View v, boolean hasFocus) {

      // When focus is lost check that the text field has valid values.

      if (!hasFocus) { {
         // Validate youredittext
      }
    }
 });
Run Code Online (Sandbox Code Playgroud)

  • 如果只有一个可聚焦的`EditText`,这不起作用.它永远不会失去焦点. (52认同)
  • 如果只有一个`EditText`,则验证用户做什么离开屏幕. (3认同)

Ren*_*eno 110

用户完成编辑后,他/她将按DoneEnter

((EditText)findViewById(R.id.youredittext)).setOnEditorActionListener(
    new EditText.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            if (actionId == EditorInfo.IME_ACTION_SEARCH ||
                    actionId == EditorInfo.IME_ACTION_DONE ||
                    event != null &&
                    event.getAction() == KeyEvent.ACTION_DOWN &&
                    event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
                if (event == null || !event.isShiftPressed()) {
                   // the user is done typing. 

                   return true; // consume.
                }                
            }
            return false; // pass on to other listeners. 
        }
    }
);
Run Code Online (Sandbox Code Playgroud)

  • 你能确定一下吗?我有进入下一个可编辑字段的习惯 - 我几乎从不按Enter/Done - 以及我从客户那里看到的内容,他们也没有......我在谈论Edittexts/Comboboxes等列表如果你只给用户一个输入字段并迫使他按下一个按钮才能进入其他领域,那么这显然是一个不同的故事...... (44认同)
  • 请记住,您还必须为编辑文本设置android:singleLine ="true".感谢http://stackoverflow.com/questions/15901863/oneditoractionlistener-not-working (3认同)
  • 如果您按下“返回”按钮以关闭键盘怎么办? (3认同)

Zim*_*XXX 55

我个人更喜欢在打字结束后自动提交.以下是您可以检测此事件的方法.

声明和初始化:

private Timer timer = new Timer();
private final long DELAY = 1000; // in ms
Run Code Online (Sandbox Code Playgroud)

听众在例如onCreate()

EditText editTextStop = (EditText) findViewById(R.id.editTextStopId);
    editTextStop.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) {
            if(timer != null)
                timer.cancel();
        }
        @Override
        public void afterTextChanged(final Editable s) {
            //avoid triggering event when text is too short
            if (s.length() >= 3) {              

                timer = new Timer();
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        // TODO: do what you need here (refresh list)
                        // you will probably need to use
                        // runOnUiThread(Runnable action) for some specific
                        // actions
                        serviceConnector.getStopPoints(s.toString());
                    }

                }, DELAY);
            }
        }
    });
Run Code Online (Sandbox Code Playgroud)

因此,当文本被更改时,计时器开始等待任何下一次更改发生.当它们发生时,计时器被取消,然后再次启动.

  • 这很棒,但要注意计时器会导致内存泄漏,所以请使用`Handler` (10认同)

Shi*_*own 21

您可以使用setOnKeyListener或使用textWatcher来执行此操作:

设置文本观察者 editText.addTextChangedListener(textWatcher);

然后打电话

private TextWatcher textWatcher = new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            //after text changed
        }

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

        @Override
        public void afterTextChanged(Editable s) {

        }
    };
Run Code Online (Sandbox Code Playgroud)

  • 我担心这不是(完整)解决方案 - 每次编辑后textWatcher都会触发 - 如果你输入hello它会触发h,e,l,l和o - 它真的不知道用户什么时候"完成" .如果TextWatcher真的知道小部件何时失去焦点并且用户继续前进,那将会很棒... (24认同)

小智 7

我是这样解决这个问题的。我用的是科特林。

        var timer = Timer()
        var DELAY:Long = 2000

        editText.addTextChangedListener(object : TextWatcher {

            override fun afterTextChanged(s: Editable?) {
                Log.e("TAG","timer start")
                timer = Timer()
                timer.schedule(object : TimerTask() {
                    override fun run() {
                        //do something
                    }
                }, DELAY)
            }

            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                Log.e("TAG","timer cancel ")
                timer.cancel() //Terminates this timer,discarding any currently scheduled tasks.
                timer.purge() //Removes all cancelled tasks from this timer's task queue.
            }
        })
Run Code Online (Sandbox Code Playgroud)


Tyl*_*vis 6

如果您想在操作后隐藏键盘,@Reno 和 @Vinayak B 会一起回答

textView.setOnEditorActionListener(new EditText.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE) {
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(textView.getWindowToken(), 0);
            return true;
        }
        return false;
    }
});

textView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (!hasFocus) {
             // your action here
        }
    }
});
Run Code Online (Sandbox Code Playgroud)


Igo*_*daš 5

尽管许多答案确实指向了正确的方向,但我认为它们都没有回答问题作者的想法。或者至少我对这个问题的理解不同,因为我正在寻找类似问题的答案。问题是“如何知道用户何时在没有按下按钮的情况下停止输入”并触发某些操作(例如自动完成)。如果你想这样做,在 onTextChanged 中启动 Timer,延迟你会认为用户停止输入(例如 500-700ms),对于每个新字母,当你启动计时器时取消较早的一个(或至少使用某种标记,当他们打勾时,他们什么都不做)。这是与我使用过的类似的代码:

new Timer().schedule(new TimerTask() {
  @Override
  public void run() {
     if (!running) {                            
        new DoPost().execute(s.toString());
  });
 }
}, 700);
Run Code Online (Sandbox Code Playgroud)

请注意,我修改了异步任务中的 running boolean 标志(任务从服务器获取 json 以进行自动完成)。

还要记住,这会创建许多计时器任务(我认为它们被安排在同一个线程上,但必须检查这个),所以可能有很多地方需要改进,但这种方法也有效,最重要的是你应该使用计时器,因为没有“用户停止输入事件”


Cri*_*ris 5

另一种方法...这是一个示例:如果用户在打字时有 600-1000 毫秒的延迟,您可能会认为他已经停止了。

 myEditText.addTextChangedListener(new TextWatcher() {
             
            private String s;
            private long after;
			private Thread t;
            private Runnable runnable_EditTextWatcher = new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        if ((System.currentTimeMillis() - after) > 600)
                        {
                            Log.d("Debug_EditTEXT_watcher", "(System.currentTimeMillis()-after)>600 ->  " + (System.currentTimeMillis() - after) + " > " + s);
                            // Do your stuff
                            t = null;
                            break;
                        }
                    }
                }
            };
            
            @Override
            public void onTextChanged(CharSequence ss, int start, int before, int count) {
                s = ss.toString();
            }
            
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }
            
            @Override
            public void afterTextChanged(Editable ss) {
                after = System.currentTimeMillis();
                if (t == null)
                {
                    t = new Thread(runnable_EditTextWatcher);
                      t.start();
                }
            }
        });
Run Code Online (Sandbox Code Playgroud)